在我的程序中,我已将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 Console
string str;
while(getline(log, str))
{
cerr << "str: " << str << endl;
/* do stuff with str here */
}
cerr << endl;
log.close();
clearLogFile();
}
void Console::clearLogFile()
{
ofstream("console.txt", ios_base::trunc);
}
第一次通过readLogFile
,一切正常。然而,之后,它开始出现问题。它将在console.txt的第一行中读取为空字符串。我通过在gvim中打开console.txt来完成程序,并监视它是如何更改的。第一次,当它正常工作时,console.txt看起来像这样:
1 moved UP.@191 191 191 0 0 0
2 Player moved.@191 191 191 0 0 0
~
~
应该如此。然后程序转到clearLogFile
,然后console.txt为空。但是,第二次,当我打开ifstream
时,console.txt看起来像这样:
1 ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@moved UP.@191 191 191 0 0 0
2 Player moved.@191 191 191 0 0 0
~
~
这次,当getline
将第一行读入str
时,str
为空。奇怪的是,cerr << "str: " << str << endl;
行仍然将str
打印为“向上移动。@ 191 191 191 0 0 0”,即使检查gdb中的str
显示它是空的。
任何人都知道这里发生了什么?
答案 0 :(得分:0)
正在写入的例程在重写文件之前没有重置它的文件位置。因此,它会在目标文件的偏移处开始。
我相信执行写操作后的cout.seekp(0)会重置写指针,从而重新启动文件开头的写操作。
但是,您可能会遇到很多问题,即日志文件内容与您使用它的方式的一致性。
评论在这里添加,因为我无法在评论框中进行格式化...
通过在每次写入后重置文件指针,输出文件中只会有一行。您需要确保在写入之前阅读它,否则新数据将被旧数据覆盖,或者更糟糕的是可能被部分覆盖。
e.g。写1:
Player moved 1 2 3 4
e.g。写2:
Player fell over
将离开:
Player fell over
3 4
在书面文件中,如果读者在作者第二次写作之前没有到达那里。
你可能最好使用显式文件,而不是使用cout,或者你可以记住读取之间的读取位置,并在执行下一次读取之前寻找它,但这会留下不断增长的日志文件。
HTH