【问题标题】:Getting failbit when reading from txt file ending in new line从以新行结尾的txt文件读取时获取失败位
【发布时间】:2020-03-20 22:00:55
【问题描述】:

我正在尝试以特定顺序读取一个简单的文本文件。在这种情况下,我读取了一个 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");
    }
}

我遇到的问题是我的文本文件以换行符结尾,导致我的程序每次将文件读取到最后时都会抛出运行时错误。如何读取整个文件而不让它返回故障位?

【问题讨论】:

    标签: c++ fstream


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 那么为什么当我的文件没有以新行结尾时会导致electronicsFile.fail() 为假?
    • @ThaAfroSamurai 那是因为你的循环中的条件是错误的。您应该将输入操作作为条件本身。所以while (electronicsFile >> barcode >> name >> price) {} 的身体是空的。
    【解决方案2】:

    我遇到的问题是我的文本文件以换行符结尾

    这不是问题。当您尝试尽可能长时间地读取元素时(为此,您的代码应该是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();
       }
    }
    

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

    【讨论】:

      猜你喜欢
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      • 2021-05-18
      • 2017-09-12
      • 1970-01-01
      相关资源
      最近更新 更多