将文本文件读入字符串

时间:2013-11-03 19:48:36

标签: c++ file-io

确定。所以我试图从一个文件中读取并将信息放入一个类中。让我解释一下:

假设我有一个看起来像这样的txt文件

1 2 3 4
5 6 7 8

现在让我说我有一个班级

class Numbers {
public:
    Numbers(int first, int second, int third, int fourth)
    : first(first), second(second), third(third), fourth(fourth){}

private:
    int first;
    int second;
    int third;
    int fourth;
};

现在,我希望文件的每一行都是Numbers的新实例,并且每行中的数字将用作每个实例的数据成员(希望这是有意义的)。

因此,在阅读上述文件后,我应该有两个Numbers实例。第一个含有(1,2,3,4),第二个含有(5,6,7,8)。我有一个函数,从文件读取后将字符串转换为int。我在创建Numbers实例时遇到了麻烦。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

为什么不直接将所有数字加载到这样的矢量中?

#include <iterator>
#include <fstream>
#include <vector>
#include <iostream>

std::vector<int> loadNumbersFromFile(const std::string& name)
{
    std::ifstream is(name.c_str());
    if (!is)
    {
        std::cout << "File could not be opened!" << std::endl;
    }
    std::istream_iterator<int> start(is), end;
    return std::vector<int>(start, end);
}

void main()
{
    std::vector<int> numbers = loadNumbersFromFile("file.txt");
}

无需为此声明一个类。

答案 1 :(得分:0)

您无需转换任何内容,因为basic_istream& operator>>(int&)已为您执行此操作

ifstream f;
f >> first;

创建Numbers实例可以像定义构造函数一样简单

Numbers() : first(0), second(0), third(0), fourth(0) {}

然后

Numbers number1, number2;

并定义

friend istream &operator>>(istream &f, Number &n) {
    f >> n.first >> n.second >> n.third >> n.fourth;
    return f;
}
你可以说

f >> number1 >> number2;

答案 2 :(得分:0)

正如其他人所指出的,int的输入运算符已经从数字序列转换为int。但是,这种转换也可以做一些可能是正确的事情:格式化的输入操作符确实跳过前导空格,不区分不同种类的空格。也就是说,如果一行包含的值少于预期,则流将很乐意从下一行读取它们!这种行为是否正确取决于具体用途。由于问题特别提到了每行包含四个值的格式,我假设每行上的值少于4个 OK。

可以使用std::noskipws防止输入操作符自动跳过空格。一旦应用了这一点,就必须明确地跳过空格。跳过空格但使用自定义操纵器无法创建换行符:

std::istream& skipspace(std::istream& in) {
    std::istream::sentry cerberos(in);
    if (in) {
        std::istreambuf_iterator<char> it(in), end;
        while (it != end
               && *it != '\n'
               && std::isspace(static_cast<unsigned char>(*it))) {
            ++it;
        }
    }
    return in;
}

使用这样的操纵器,实现读取一行值非常简单,如果没有足够的值,则会失败:

  1. 关闭自动跳过空格。
  2. 使用std::ws跳过前导空格,以摆脱前一行结尾和行上可能的前导空格。
  3. 读取每个值,仅跳过对象之间的非换行符。
  4. 也就是说,类Numbers的输入运算符如下所示:

    std::istream& operator>> (std::istream& in, Numbers& numbers) {
        int first, second, third, fourth;
        if (in >> std::noskipws
            >> std::ws >> first
            >> skipspace >> second
            >> skipspace >> third
            >> skipspace >> fourth) {
            numbers = Numbers(first, second, third, fourth);
        }
        return in;
    }