1

我编写了一个命令行程序,该程序将通过管道逐行清理和重组我们存档的服务器日志到新的目标文件。每个目标文件都有一个相应的正则表达式过滤器项,因此如果源文件中的红色行与正则表达式匹配,则会被写入此特定目标文件。

我从配置文件中读取了正则表达式字符串及其目标文件字符串,并将这些信息保存在向量中,以便能够使用配置中的每个新的标记/过滤器对动态调整它们的大小。

以下代码显示了我如何循环遍历所有源文件,并且对于每个源文件,我逐行读取,对于可能为红色的每一行,我循环遍历配置中定义的所有过滤器,如果正则表达式与该行匹配我将这一行写入到 ofstream。每次我这样做时,在我打开新的目标文件之前,ofstream 都会被 close()d 和 clear()ed。

我现在的问题是一切正常,除了我的目标文件在程序结束后只包含 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);
}
4

2 回答 2

5

尝试为您的文件“附加”打开模式,我猜它会是 ios_base::app (请参阅重新打开函数,第三个参数)。

std::ios_base::out | std::ios_base::app
于 2010-11-19T15:04:36.807 回答
0

您需要通过添加 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 从开头开始并覆盖其他所有内容。

资源

于 2013-05-29T22:18:45.020 回答