-2

我正在编写一个程序来从文件中获取输入并将其显示在控制台上。问题是最后一个条目被重复了两次。代码如下:-

int main(void)
{
    string filename;
    int grades;
    cout<<"Enter the filename:"<<endl;
    getline(cin,filename);
    ifstream inFile(filename.c_str(),ios::in);
    if(!inFile){
        cout<<"File does not exist."<<endl;
        exit(1);
    }
    while(!inFile.eof())
    {
        inFile>>grades;
        cout<<grades<<endl;
    }
    inFile.close();
    return 0;
}

你能帮我找出错误吗?我在网上搜索过,我的代码在语法和逻辑上似乎都是正确的。

4

2 回答 2

2

这是错误的

while(!inFile.eof())
    {
        inFile>>grades;
        cout<<grades<<endl;
    }

这是正确的

while (inFile >> grades)
{
   cout << grades << endl;
}

一定是这个论坛上最常见的错误。eof()不会告诉您下一次读取将有文件结束错误,它会告诉您最后一次读取由于文件结束而失败。所以如果你必须使用eof()你应该在你阅读之后使用它而不是之前

于 2013-09-03T12:37:46.893 回答
0

语法正确,是的。但不合逻辑。你使用 eof()不正确。

首先要意识到的是,所有测试状态的函数都基于上次输入的结果。在使用您输入的任何内容之前,您必须始终检查输入是否成功;当你写:

inFile >> grades;
std::cout << grades;

没有在访问成绩之前验证输入是否成功。在这种情况下,如果输入失败,则得到之前的值;如果没有先前的值,您会得到未定义的行为。>>在和之间的某个地方<<,您必须检查是否>>成功。

检查成功的常用方法是将流本身用作布尔值。而且由于>>返回对流的引用,因此编写循环的惯用方式是:

while ( inFile >> grades ) {
    std::cout << grades << std::endl;
}

从软件工程的角度来看,这很可怕(在 a 的条件下修改状态while),但是这个成语无处不在,以至于其他任何事情都会引发问题。

如果由于任何原因出现输入错误,这将停止。一旦你看到了失败(并且只有那时),你可以问为什么:

if ( inFile.bad() ) {
    //  Serious hardware failure...
} else if ( !inFile.eof() ) {
    //  Format error in the input...
} else {
    //  Normally, no more data in the input stream, but
    //  there are a few special cases where you could still
    //  have a format error and end up here.  Not with
    //  `int`, however.
}

但同样,这在输入失败后才有效。

于 2013-09-03T13:39:48.833 回答