为什么 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
我试图让我的程序从数据 (.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