我正在尝试从数据(.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()
循环时我都必须阅读多行。
答案 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