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

Why is eof() never returning true?

我试图让我的程序从数据 (.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' 字符。你们知道如何解决这个问题吗?

编辑 2:这个问题不同于:Why is iostream::eof inside a loop condition considered wrong? 因为我每次 运行 通过我的 while 循环时都必须阅读不止一行。

您必须将这一行 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

the next available input character c equals delim, as determined by Traits::eq(c, delim). This character is not extracted

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

您使用 std::istream::get 的问题在于它不使用定界符。它在第一次调用时工作正常,但下一次调用将立即看到上一次调用遗留下来的换行符,而不是读取任何内容。

如果你想阅读行,要么使用我推荐的std::istream::getline (if you persist on using character arrays) or std::getline with std::string


您也不需要显式 eof 检查,而是依赖于所有函数 returns (引用)流和流可以是 used directly in conditions ,例如

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