0

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

假设我有一个看起来像这样的 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 实例时遇到问题。有任何想法吗?

4

3 回答 3

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");
}

无需为此声明一个类。

于 2013-11-03T20:03:34.900 回答
0

正如其他人指出的那样,输入运算符 forint已经将数字序列转换为int. 然而,这种转换也做了一些可能是也可能不是正确的事情:格式化的输入运算符会跳过前导空格,而不是区分不同类型的空格。也就是说,如果一行包含的值比预期的要少,流将愉快地从下一行读取它们!这是否正确的行为取决于确切的使用。由于该问题特别提到了每行包含四个值的格式,因此我假设每行的值少于 4 个是不行的。

可以使用 防止输入运算符自动跳过空格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. 读取每个值,仅跳过对象之间的非换行符。

也就是说,该类的输入运算符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;
}
于 2013-11-03T20:28:23.260 回答
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;
于 2013-11-03T19:54:21.483 回答