2010-06-25 3 views
0

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

1 moved [email protected]91 191 191 0 0 0 
    2 Player [email protected] 191 191 0 0 0 
~ 
~ 

, которая, как это должно быть. Затем программа переходит к clearLogFile, а затем console.txt пуст. Тем не менее, второй раз через, когда я открываю ifstream, console.txt выглядит следующим образом:

1 ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ 
    ^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@moved [email protected] 191 191 0 0 0 
    2 Player [email protected] 191 191 0 0 0 
~ 
~ 

На этот раз, когда getline читает первую строку в str, str пустые. Странно, линия cerr << "str: " << str << endl; по-прежнему печатает str как «перемещенный UP. @ 191 191 191 0 0 0», хотя проверка str в gdb показывает, что она пуста.

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

ответ

0

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

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

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

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

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

например. напишите 1:

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

Player fell over 

оставить бы:

Player fell over 
3 4 

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

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

HTH

+0

Это решило проблему, спасибо. Какие проблемы, по-вашему, я буду иметь? Любые предложения о том, как я могу использовать его лучше? – Max

+0

Сбрасывая указатель файла после каждой записи, в выходном файле будет только одна строка. Вам нужно убедиться, что вы прочитали его, прежде чем писать, иначе новые данные будут переписаны старыми данными или, что еще хуже, могут быть частично перезаписаны. , например. первый записи: Игрок переехал 1 2 3 4 5 Второй записи: Игрок упал оставляет следующее в файле: Игрок упал если читатель не добраться до файл, прежде чем писатель напишет второе сообщение. Это одна из основных проблем синхронизации. – Petesh

+0

Я положил 'cout.seekp (0)' после 'ofstream (" console.txt ", ios_base :: trunc);' в 'clearLogFile', поэтому он только сбросит указатель после того, как я очищу все из console.txt, не после каждой записи. До сих пор он работает нормально. Вы видите другие проблемы? – Max

Смежные вопросы