为什么eof()永远不会返回true?

时间:2015-11-07 07:49:16

标签: c++ file-read

我正在尝试从数据(.dat)文件(实际上只是一个文本文件)中读取数据。所以当然我正在使用循环条件while(!file.eof()),但这永远不会返回true。这是我的功能:

void Table::readIn(const char finput[]){
    std::ifstream file;

    file.open(finput);

    if (!file.is_open())
    {
        std::cout << "Cannot open " << finput << std::endl;
        return;
    }
    char key[100];
    file.get(key, 99, '\n');
    while (!file.eof())
    {
        stock * item = new stock;
        item->setTick(key);
        file.get(key, 99, '\n');
        item->setName(key);
        file.get(key, 99, '\n');
        item->setValue(atof(key));
        file.get(key, 99, '\n');
        item->setDate(key);
        file.get(key, 99, '\n');
        item->setYearReturn(atof(key));
        file.get(key, 99, '\n');
        addStock(item);
    }
}

这是我的数据文件中的内容:

TSLA
Tesla Motors, Inc.
30160000000
November 6, 2015
13.1

我希望我能给你们更多的信息,但是程序循环遍历while (!file.eof())循环的事实是我对此问题的全部了解。

编辑:我通过调试器运行它,在while循环的每一行都有一个断点。我发现第一个get()调用(在while循环之前)将key设置为正确的值,但在get()之后调用key调用""'\n'。我假设这是因为程序永远不会读取文件中的第一个while字符。你们知道如何解决这个问题吗?

编辑2:此问题与:Why is iostream::eof inside a loop condition considered wrong?不同,因为每次运行jButton1ActionPerformed()循环时我都必须阅读多行。

2 个答案:

答案 0 :(得分:3)

使用std::istream::get的问题在于它不使用分隔符。它可以在第一次通话时正常工作,但接下来的通话会立即看到上一次通话中遗留的换行符,而不会读取任何内容。

如果您想阅读行,请使用std::istream::getline(如果您坚持使用字符数组)或std::getline std::string这是我推荐的。

您也不需要显式eof检查,而是依赖于所有函数返回(引用)流并且流可以是used directly in conditions的事实,所以例如

if (!std::getline(...))
    // end of file or error

答案 1 :(得分:0)

您必须用

替换此行while (!file.eof())
while (true)
    {
        /*code*/
        file.get(key, 99, '\n');
        if (file.eof()) { break; } // and similarly for other usages where you are reading the stream
        /*code*/
    }

编辑: 好。看起来你的问题就在这里,引用documentation of ifstream::get

  

下一个可用的输入字符c等于delim,由Traits :: eq(c,delim)确定。不提取此字符

因此,在每次调用获取之后,您的搜索指针仍然指向分隔符。所以在第一次调用之后,get会不断遇到换行符,从而返回一个空数据。您可以添加虚拟读取以使用该分隔符,甚至可以更好地使用getline