2010-11-19 4 views
1

Ich schrieb ein Kommandozeilenprogramm, das unsere archivierten Serverprotokolle säubern und reorganisieren sollte, indem wir Zeile für Zeile an neue Zieldateien weiterleiten. Jede Zieldatei hat ein entsprechendes RegEx-Filterelement, wenn also die Zeile, die aus der Quelldatei rot ist, in diese spezifische Zieldatei geschrieben wird, wenn sie mit der RegEx übereinstimmt.C++ ofstream - nur 1 String wird in Datei geschrieben, vorherige Zeichenfolge wird überschrieben, warum?

Ich lese die RegEx-Strings und ihre Zieldatei-Strings aus einer Konfigurationsdatei und speichere diese Informationen in Vektoren, um sie mit jedem neuen Taget/Filter-Paar, das aus der Konfig rot ist, dynamisch um eins zu vergrößern.

Das folgende Stück Code zeigt, wie ich alle meine Quelldateien durchlaufe und für jede einzelne Zeile zeilenweise lese und für jede Zeile, die rot sein könnte, durchlaufe ich alle in der Konfiguration definierten Filter und wenn die regEx stimmt mit der Zeile überein, in die ich diese Zeile an ofstream schreibe. Jedes Mal, wenn ich dies tue, erhält der Ofstream close() d und clear() ed, bevor ich die neue Zieldatei darin öffne.

Mein Problem ist jetzt, dass alles gut funktioniert, außer dass meine Zieldateien nur 1 einzelne Zeichenfolge enthalten, nachdem das Programm endet. Es enthält die letzte Zeichenfolge, die ich in die Datei geschrieben habe.

Alle Zeichenfolgen, die ich zuvor in die Datei geschrieben habe, scheinen überschrieben zu werden. Ich denke, ich mache etwas falsch, aber ich sehe nicht, was es ist.

Hier ist der Code-Extrakt:

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; 
    } 
} 
} 

EDIT:

i die Funktion wieder zu öffnen habe ich vergessen

verwenden
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); 
} 

Antwort

5

Versuchen offenen Modus für die Datei "anhängen", ich denke, es wird sei ios_base :: app (siehe reopen-Funktion, 3. Argument).

std::ios_base::out | std::ios_base::app 
+0

Vielen Dank! Jetzt funktioniert es großartig! –

0

Sie müssen sich auf Zufügen-Modus in diesem Verfahren drehen durch Zugabe von std :: ofstream :: app

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

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

standardmäßig werden sollte der Modus std :: ofstream :: out beginnt am Anfang und überschreibt alles andere.

Source