0

在我的程序中,我已将标准输出重定向到打印到文件“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将第一行读入时strstr是空白的。奇怪的是,该cerr << "str: " << str << endl;行仍然打印str为“moved UP.@191 191 191 0 0 0”,尽管str在 gdb 中检查显示它是空的。

有人知道这里发生了什么吗?

4

1 回答 1

0

正在写入的例程不会在重写文件之前重置它的文件位置。结果,它从目标文件的偏移量开始。

我相信执行写入后的 cout.seekp(0) 将重置写入指针,从而在文件开头重新开始写入。

但是,您可能会在日志文件内容的一致性与您使用它的方式方面遇到很多问题。

此处添加了评论,因为我无法在评论框中获取格式...

通过在每次写入后重置文件指针,输出文件中只会有一行。您需要确保在写入之前阅读它,否则新数据将被旧数据覆盖,或者更糟糕的是可能被部分覆盖。

例如写1:

Player moved 1 2 3 4

例如写2:

Player fell over

会离开:

Player fell over
3 4

在写入文件中,如果在作者第二次写入之前读者没有到达那里。

使用显式文件而不是使用 cout 可能会更好,或者您可以记住读取之间的读取位置并在执行下一次读取之前查找该位置,但这会给您留下一个不断增长的日志文件。

高温高压

于 2010-06-25T19:52:45.287 回答