我编写了一个命令行程序,它将通过逐行管理新目标文件来清理和重新组织我们的归档服务器日志。每个目标文件都有一个相应的regEx过滤器项,因此如果与源文件中的红色行匹配regEx,则该行将被写入此特定目标文件。
我从配置文件中读取了regEx字符串及其目标文件字符串,并将这些信息保存在向量中,以便能够使用配置中红色的每个新taget /过滤器对动态调整它们的大小。
以下代码显示了我如何循环遍历所有源文件,并且我逐行读取每个源文件,对于每行可能是红色的,我循环遍历配置中定义的所有过滤器以及regEx匹配我将此行写入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);
}
答案 0 :(得分:5)
尝试为你的文件“附加”打开模式,我猜它将是ios_base :: app(参见reopen function,3rd argument)。
std::ios_base::out | std::ios_base::app
答案 1 :(得分: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,它从头开始并覆盖其他所有内容。