C++ 读取以新行结尾的txt文件时获取故障位

C++ 读取以新行结尾的txt文件时获取故障位,c++,fstream,C++,Fstream,我试图以特定的顺序从一个简单的文本文件中读取。在本例中,我读取一个int,然后是string,然后是double。以下是文本文件: 54321 Television 250 46782 Laptop 1200 23461 Ipad 500 87612 Playstation 400 下面是我用来检查文件错误(错误类型或错误文件名)的函数: 我遇到的问题是,我的文本文件以换行符结尾,导致我的程序在每次将文件读到结尾时都抛出运行时错误。如何读取整个文件而不让它返回故障位?首先,循环条件应该是输入

我试图以特定的顺序从一个简单的文本文件中读取。在本例中,我读取一个int,然后是string,然后是double。以下是文本文件:

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

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


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

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

while(电子文件>>条形码>>名称>>价格){
;//空体
}
在此之后,
electronicsFile.fail()
将在循环完成后始终为true。循环退出的唯一方式是读取无效或到达文件末尾

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

if(!electronicsFile.eof()){
抛出运行时_错误(“读取电子文件时出错”);
}
我遇到的问题是,我的文本文件以换行符结尾

这不是问题。当您尝试尽可能长时间地读取元素时(要做到这一点,您的代码应该是
,而(electronicsFile>>条形码>>名称>>价格)
),您将遇到设置的故障位,因为这会阻止您无限期地从
electronicsFile
读取。您可以始终
clear()
清除流

如果您确实想在读取时检查文件是否不正确,您可以单独检查每个读取语句,再加上*检查
.eof()
,而不是
.fail()

intmain(){
std::fstream electronicsFile{“logi.txt”};
int条码=0;
std::字符串名;
双倍价格=0.0;
试一试{
for(auto c=electronicsFile.get();!electronicsFile.eof();){
电子文件回拨(c);
const auto message=“读取电子文件时出错”;
如果(!(电子文件>>条形码))抛出std::runtime\u错误(消息);
如果(!(电子文件>>名称))抛出std::runtime\u错误(消息);
如果(!(电子文件>>价格))抛出std::runtime\u错误(消息);
}
}捕获(const std::runtime_error&ex){

std::cerr那么,为什么当我的文件没有以新行结尾时,它会导致
electronicsFile.fail()
为false?@ThaAfroSamurai这是因为循环中的条件是错误的。你应该将输入操作作为条件本身。所以
while(electronicsFile>>条形码>>名称>>价格){}
的主体是空的。
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");
    }
}
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();
   }
}