0

可能重复:
C++ 中的文件结尾

我编写了一个从 .txt 文件中读取数据的函数,但是当我调用它时,它一直在崩溃。这是代码:

void beolvas(vector<int> &charge, vector<int> &deliver, vector<Robot*> &robots) {
    string s;
    ifstream f;

    do {
        cout << "Add meg a filenevet" << endl;
        cin >> s;
        f.open(s.c_str());
    } while (!f.good());

    cout << "adatok beolvasasa..." << endl;

    int napok;
    if (!(f >> napok)) throw 1;
    charge.resize(napok);
    deliver.resize(napok);

    for (int i = 0; i<napok; i++) {
        if (!(f>>charge[i])) throw 1;
        if (!(f>>deliver[i])) throw 1;
    }

    string type, name;
    int battery;
    while (!f.eof()) {
        cout << " a ";
        if (f>>type && f>>name && f>>battery) {
            if (type=="Mac") {
                Mac r = Mac(name,battery);
                robots.push_back(&r);
            };
            if (type=="Eco") {
                Eco r = Eco(name,battery);
                robots.push_back(&r);
            };
            if (type=="Pro") {
                Pro r = Pro(name,battery);
                robots.push_back(&r);
            };
        };
    };
}

似乎问题发生在while循环中。如果我想从 3 行长的文本中读取,我会在屏幕上看到 4 个字母(我让程序在读取每一行之前打印一个)。

f.eof()不是我这里需要用到的功能?

4

2 回答 2

1

这是读取文件时最常见的问题之一。检查f.eof()只会告诉您之前的读取是否到达文件末尾。因此,在最后一次成功读取之后(您打印了第三个“a”),eof()返回 false 并且您的循环再执行一次,输出一个额外的“a”。

相反,使用您的提取线作为while循环的条件:

while (f>>type && f>>name && f>>battery) {
    if (type=="Mac") {
        Mac r = Mac(name,battery);
        robots.push_back(&r);
    }
    if (type=="Eco") {
        Eco r = Eco(name,battery);
        robots.push_back(&r);
    }
    if (type=="Pro") {
        Pro r = Pro(name,battery);
        robots.push_back(&r);
    }
}

这是有效的,因为只要您的一个提取到达文件末尾,while条件就会为假并且循环不会执行。

如果您想在格式错误的行之后继续,我建议您std::getline改用:

std::string line;
while (std::getline(f, line)) {
  std::stringstream ss(line);
  if (ss >> type && ss >> name && ss >> battery) {
    // ...
  }
}

使用这种std::getline方法的原因是,如果半行的格式正确,您就会遇到问题。您的方法可能会读入type然后name失败,battery并且循环的下一次迭代将从同一个地方开始。

您还会遇到问题,因为您将指向具有自动存储持续时间的对象的指针推送到某些向量中。当创建对象的块结束时,指针将指向无效对象。

于 2012-12-20T14:13:11.770 回答
0

这是一个常见问题解答。在 C/C++ 中,文件结束条件仅在您尝试读取结束后触发。因此,您不能从 feof() == false 假设输入可用(因为您可能正好位于文件末尾,但尚未超过它)。您应该始终在读取操作测试有效输入。

于 2012-12-20T14:19:28.763 回答