从以新行结尾的 txt 文件读取时获取 failbit

Getting failbit when reading from txt file ending in new line

我正在尝试以特定顺序读取一个简单的文本文件。在这种情况下,我读取了一个 int,然后是 string,然后是 double。这是文本文件:

54321 Television
250
46782 Laptop
1200
23461 Ipad
500
87612 Playstation
400

这是我用来检查文件错误(错误类型或错误文件名)的函数:

void Electronics::ReadData(istream& electronicsFile)
{
    int barcode;
    string name;
    double price;

    while (electronicsFile.good()) {
        electronicsFile >> barcode >> name >> price;
    }
    if (electronicsFile.fail()) {
        throw runtime_error("Error reading electronics file");
    }
}

我 运行 遇到的问题是我的文本文件以换行符结尾,导致我的程序每次读取文件到最后都会抛出运行时错误。我怎样才能读取整个文件而不是 return 一个故障位?

首先,你的循环条件应该是输入操作本身。

while (electronicsFile >> barcode >> name >> price) {
  ; // empty body
}

在此之后,electronicsFile.fail() 将在循环结束后始终为真。循环退出的唯一方法是读取无效或到达文件末尾。

因此您应该将条件更改为仅在未到达文件末尾时抛出。

if (!electronicsFile.eof()) {
  throw runtime_error("Error reading electronics file");
}

The issue that I am running into is that my text file ends with a newline

这不是问题。当您尝试尽可能长时间地读取元素时(为此,您的代码应该是 while (electronicsFile >> barcode >> name >> price);),您 遇到设置的失败位,因为 这就是阻止你无限期阅读 electronicsFile 的原因。不过,您始终可以 clear() 直播。

如果你真的想在读取时检查文件是否不正确,你可以分别检查每个读取语句加上*检查 .eof(),而不是 .fail():

int main() {
   std::fstream electronicsFile {"logi.txt"};

   int barcode = 0;
   std::string name;
   double price = 0.0;

   try {
       for (auto c = electronicsFile.get(); !electronicsFile.eof();) {
           electronicsFile.putback(c);
           const auto message = "Error reading electronics file";
           if (!(electronicsFile >> barcode)) throw std::runtime_error(message);
           if (!(electronicsFile >> name)) throw std::runtime_error(message);
           if (!(electronicsFile >> price)) throw std::runtime_error(message);
       }
   } catch (const std::runtime_error& ex) {
       std::cerr << ex.what();
   }
}

这将正确地流过文件中存储的正确数据的执行过程,并在文件数据不正确的情况下中止并打印异常消息。