我编写了一个命令行程序,该程序将通过管道逐行清理和重组我们存档的服务器日志到新的目标文件。每个目标文件都有一个相应的正则表达式过滤器项,因此如果源文件中的红色行与正则表达式匹配,则会被写入此特定目标文件。
我从配置文件中读取了正则表达式字符串及其目标文件字符串,并将这些信息保存在向量中,以便能够使用配置中的每个新的标记/过滤器对动态调整它们的大小。
以下代码显示了我如何循环遍历所有源文件,并且对于每个源文件,我逐行读取,对于可能为红色的每一行,我循环遍历配置中定义的所有过滤器,如果正则表达式与该行匹配我将这一行写入到 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);
}