странные данные мусора при открытии ранее усеченного файла - PullRequest
0 голосов
/ 25 июня 2010

В моей программе я перенаправил стандартный вывод для печати в файл '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 он будет читаться как пустая строка.Я прошел программу с открытым console.txt в gvim и посмотрел, как он изменился.Первый раз, когда он работал правильно, 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", хотя проверка str в gdb показывает, что она пуста.

Кто-нибудь знает, что происходитздесь

1 Ответ

0 голосов
/ 25 июня 2010

Пишущая подпрограмма не сбрасывает позицию файла перед перезаписью в файл. В результате он начинается со смещения в целевом файле.

Я полагаю, что cout.seekp (0) после выполнения записи сбросит указатель записи, тем самым возобновив запись в начале файла.

Возможно, у вас возникнет много проблем с согласованностью содержимого файла журнала с тем, как вы его используете.

Здесь добавлен комментарий, так как я не могу получить форматирование в поле для комментариев ...

Сбрасывая указатель файла после каждой записи, в выходном файле всегда будет только одна строка. Вам необходимо убедиться, что вы прочитали его, прежде чем писать в него, иначе новые данные будут перезаписаны старыми, или, что еще хуже, могут быть частично перезаписаны.

например. написать 1:

Player moved 1 2 3 4

например. написать 2:

Player fell over

Уйдет:

Player fell over
3 4

В записанном файле, если читатель не дошел до того, как писатель сделал вторую запись.

Возможно, вам лучше использовать явный файл, чем использовать cout, или вы можете запомнить позицию чтения между чтениями и искать ее перед выполнением следующего чтения, но это оставляет вас с постоянно растущим лог-файлом.

НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...