输入文件读取错误值,并且 eof 控制循环未结束

Input file reading wrong value and eof controlled loop does not end

提问人:Derek 提问时间:1/20/2018 更新时间:1/20/2018 访问量:153

问:

我正在尝试使用一个循环从输入文件中读取数据,该循环应该在函数中文件的末尾停止。文件中的数据排列如下:

 Zip Drive
 89
 Warehouse C
 75.89
 Keyboard
 133
 Warehouse C
 25.95

在第四行,变量填充了一些垃圾输入,之后读取的所有内容都是空白的。循环也不会结束。

int ReadData(string productName[], string productLocation[], int productQty[], double productPrice[])
{
    ifstream infile;
    int i = 0;
    infile.open("prog1.txt");

    do {
        getline(infile, productName[i]);
        infile >> productQty[i];
        getline(infile, productLocation[i]);
        infile >> productPrice[i];
        i++;
    } while (!infile.eof());

    infile.close();
    return i;
} 
C++ 文件-IO IFSTREAM EOF

评论

1赞 Barmar 1/20/2018
为什么循环条件中的 iostream::eof 被认为是错误的可能重复?
0赞 Barmar 1/20/2018
另请参阅 stackoverflow.com/questions/10553597/...
1赞 Barmar 1/20/2018
上一个问题中,有人向你介绍了这些问题
0赞 user4581301 1/20/2018
如果文件读取由于文件结束以外的某种原因而失败,您希望循环如何停止?方便阅读: stackoverflow.com/a/7868998/4581301 看看您是否可以利用选项 2。
0赞 Derek 1/20/2018
我已经解决了使用eof作为循环条件在我的作业指南中,并且我还进行了编辑以解释我尝试了.ignore(),它适用于我的productLocation问题,但不适用于productPrice。

答:

1赞 Remy Lebeau 1/20/2018 #1

and 语句正在读取 / 值,并在流中将换行符保留在它们之后,以供下一次调用读取,这不是您想要发生的。infile >> productQty[i]infile >> productPrice[i]intdoublestd::getline()

您需要:

  1. 用于读取每一行,然后用于解析各自行中的 / 值:std::getline()std::istringstreamintdouble

    int ReadData(string productName[], string productLocation[], int productQty[], double productPrice[])
    {
        ifstream infile("prog1.txt");
        int i = 0;
    
        while (getline(infile, productName[i]))
        {
            getline(infile, line);
            istringstream(line) >> productQty[i];
            getline(infile, productLocation[i]);
            getline(infile, line);
            istringstream(line) >> productPrice[i];
            ++i;
        }
    
        infile.close();
        return i;
    }
    
  2. 读取 / 值后调用,以读取并消除换行符:infile.ignore()intdouble

    int ReadData(string productName[], string productLocation[], int productQty[], double productPrice[])
    {
        ifstream infile("prog1.txt");
        int i = 0;
    
        while (getline(infile, productName[i]))
        {
            infile >> productQty[i];
            infile.ignore(numeric_limits<streamsize>::max(), '\n');
            getline(infile, productLocation[i]);
            infile >> productPrice[i];
            infile.ignore(numeric_limits<streamsize>::max(), '\n');
            ++i;
        }
    
        infile.close();
        return i;
    }
    

无论哪种情况,都必须为数组预先分配足够的元素,以容纳文件中尽可能多的产品。由于代码无法实际验证该计数,因此我建议采用另一种更安全的方法:

struct productInfo
{
    string name;
    string location;
    int quantity;
    double price;
};

istream& operator>>(istream &in, productInfo &out)
{
    string line;

    if (!getline(in, out.name)) {
        // don't set failbit yet, in case this is just EOF...
        return in;
    }

    // at this point, a new product is encountered, so
    // any missing data is considered a failure...

    if (!getline(in, line)) {
        in.setstate(failbit);
        return in;
    }

    if (!(istringstream(line) >> out.quantity)) {
        in.setstate(failbit);
        return in;
    }

    if (!getline(in, out.location)) {
        in.setstate(failbit);
        return in;
    }

    if (!getline(in, line)) {
        in.setstate(failbit);
        return in;
    }

    if (!(istringstream(line) >> out.price)) {
        in.setstate(failbit);
        return in;
    }

    return in;
}

int ReadData(vector<productInfo> &products)
{
    ifstream infile("prog1.txt");
    int i = 0;

    productInfo info;
    while (infile >> info)
    {
        products.push_back(info);
        ++i;
    }

    infile.close();
    return i;
}