在我的程序中,我已将stdout重定向到打印到'console.txt'文件。函数会像这样写入该文件:
void printToConsole(const std::string& text, const TCODColor& fc, const TCODColor& bc)
{
// write the string
cout << text << "@";
// write the two color values
cout << static_cast<int>(fc.r) << " "
<< static_cast<int>(fc.g) << " "
<< static_cast<int>(fc.b) << " "
<< static_cast<int>(bc.r) << " "
<< static_cast<int>(bc.g) << " "
<< static_cast<int>(bc.b) << " " << endl;
}
我有一个从该文件中读取的函数,如下所示:
void Console::readLogFile()
{
ifstream log("console.txt", ifstream::in);
if(!log.is_open())
{
cerr << "ERROR: console.txt not found!" << endl;
return;
}
// read new input into the stack
char str[256];
while(!log.eof())
{
log.getline(str, 256);
cerr << "str: " << str << endl;
stk.push(static_cast<string>(str));
// stk is a std::stack<std::string> member of the class this function
// belongs to.
}
cerr << endl;
/* Do some stuff with str and stk here */
log.close();
clearLogFile();
}
void Console::clearLogFile()
{
FILE* log;
log = fopen("console.txt", "w");
fclose(log);
}
通常,调用readLogFile
时console.txt为空。我希望在这种情况下while(!log.eof())
循环永远不会执行,但确实如此。文件中始终至少有一个无关的空白行,有时是两行,当从文件中读取输入时,输入行夹在两个空行之间。在调用此函数后,while(!log.eof())
循环进入无限循环,从文件中拉出空行。该程序的典型代表如下:
str:
str: Player moved.@191 191 191 0 0 0
str:
str:
str: Player moved.@191 191 191 0 0 0
str:
str: // there should be a 'Player moved.' line in here
str:
str: // here as well
str:
str: // also here
str:
str:
str: Player moved.@191 191 191 0 0 0
str:
str:
str:
str:
str:
str:
str:
(onto infinite loop)
谁能看到我在这里做错了什么?
编辑:正如Amardeep建议的那样,我将while(!log.eof())
循环更改为do{...}while(!log.fail);
循环。这解决了无限循环问题,但没有解决外来线。该程序的行为与以前一样,除非它曾经进入无限循环,它现在只读取空白行,它应该读取输入,如下所示:
str:
str:
str:
str:
(etc.)
答案 0 :(得分:1)
eof()状态。您应该更改您的读取循环以执行getline()然后检查fail()状态而不是依赖于eof(),这不包括尝试读取文件时可能出错的广度。
答案 1 :(得分:1)
用于读取文件的标准反模式。
while(!log.eof())
{
log.getline(str, 256);
cerr << "str: " << str << endl;
stk.push(static_cast<string>(str));
// stk is a std::stack<std::string> member of the class this function
// belongs to.
}
试试这个:
while(log.getline(str, 256))
{
cerr << "str: " << str << endl;
stk.push(string(str));
}
这是有效的,因为getline()方法返回对流的引用。
当一个流在布尔上下文中使用时,它会被转换为bool(对于迂腐而言不是真的,但对于初学者来说就好了)。如果在读取之后流(即读取工作)仍处于良好状态,则将其转换为true。如果流处于错误状态(即读取失败),则将其转换为false。因此,如果读取工作,则进入循环。如果读取失败(因为可能读取了EOL),则不输入循环。
请注意您的版本失败,因为您在读取(getline())后未测试eof()。这是因为最后一次好的读取读取了EOF之前的所有字符。但这意味着未设置eof标志。直到您尝试实际读取EOF(只有在最后一次读取后读取所有其他字符后才会读到的内容)才能读取EOF标志。
PS。 有一个自由函数可以从流中读取字符串。
std::string line;
std::getline(log, line);