C++ ofstream - в файл записывается только 1 строка, предыдущая строка перезаписывается, почему?

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

Я читаю строки regEx и их строки целевого файла из файла конфигурации и сохраняю эту информацию в векторах, чтобы иметь возможность динамически изменять их размер на единицу с каждой новой парой тегов/фильтров, которая отмечена красным цветом в конфигурации.

Следующий фрагмент кода показывает, как я перебираю все мои исходные файлы, и для каждого из них я читаю строку за строкой, и для каждой строки, которая может быть красной, я перебираю все фильтры, определенные в конфигурации, и если регулярное выражение соответствует строке Я пишу эту строку в офстрим. Каждый раз, когда я делаю это, поток ofstream закрывается() и очищается(), прежде чем я открываю в нем новый целевой файл.

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

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

Вот выдержка из кода:

    void StringDirector::redirect_all() {
 ifstream input;  //Input Filestream init
 ofstream output; //Output Filestream init
 string transfer; //Transfer string init
 //regex e;

 for (unsigned k = 0; k<StringDirector::v_sources_list.size(); k++) {  //loop through all sources in v_sources_list vector

  cout << endl << "     LOOP through sources! Cycle #" << k << " / string is: " << StringDirector::v_sources_list[k] << endl;

  input.close();  //close all open input files
  input.clear();  //flush
  input.open(StringDirector::v_sources_list[k].c_str());  //open v_sources_list[k] with input Filestream
  if (!input) {
   std::cout << "\nError, File not found: " <<  StringDirector::v_sources_list[k] << "\nExiting!";  //Throw error if file cannot be opened
   exit(1);
  }
  cout << endl << "     " << StringDirector::v_sources_list[k] << " opened" << endl;
  getline(input, transfer); //get a first line from input Filestream and write to transfer string
  while (input) {  //do that as long as there is input
    for (unsigned j = 0; j<StringDirector::v_filters_list.size(); j++) {  //loop through all filters in v_filters_list vectord
     cout << endl << "     LOOP through filters! Cycle #" << j << " / string is: " << StringDirector::v_filters_list[j] << endl;
     regex e(StringDirector::v_filters_list[j]);
     if (regex_search(transfer, e)) {
      reopen(output, StringDirector::v_targets_list[j].c_str());
      output << transfer << endl;
      cout << endl << "          -- MATCH! Writing line to: " << StringDirector::v_targets_list[j] << endl ;
     }
    }
    getline(input, transfer);
    if (input )cout << endl << "+ got another line: " << transfer << endl;
    else cout << endl << "End Of File!" << endl;
  }
 }
}

РЕДАКТИРОВАТЬ:

я забыл функцию повторного открытия, которую я использую

    template <typename Stream>
void reopen(Stream& pStream, const char * pFile,
            std::ios_base::openmode pMode = ios_base::out)
{
    pStream.close();
    pStream.clear();
    pStream.open(pFile, pMode);
}

person Daniel Stefanovski    schedule 19.11.2010    source источник


Ответы (2)


Попробуйте «добавить» режим открытия для вашего файла, я думаю, это будет ios_base::app (см. функцию повторного открытия, 3-й аргумент).

std::ios_base::out | std::ios_base::app
person Ben Affleck    schedule 19.11.2010

Вам нужно включить режим добавления в этом методе, добавив std::ofstream::app

input.open(StringDirector::v_sources_list[k].c_str());

должен стать

input.open(StringDirector::v_sources_list[k].c_str(), std::ofstream::app);

по умолчанию используется режим std::ofstream::out, который запускается с самого начала и перезаписывает все остальное.

Источник

person Wolf    schedule 29.05.2013