2017-03-10 6 views
1

Ich versuche, eine Datei in eine andere Datei zu kopieren, aber ein Wort mit dem, was der Benutzer eingegeben hat, zu ändern. Bisher habe ich mit diesem kommen:Wie wird eine Datei in eine andere Datei kopiert, aber ein Wort durch ein vom Benutzer eingegebenes Wort ersetzt?

while (getline(openningTheFile, line, ' ')) //line is a string and openningTheFile is an ifstream 
{ 
    if (line == wordToBeDeleted) 
    { 
     line = wordToReplaceWith; 

    } 
    if (line == "\n") 
    { 
     newFile << endl; //newFile is an ofstream 
    } 

    newFile << line << " "; 
} 

Aber das Problem ist, dass dieser Code nicht das Wort liest nach dem "\n", weil die Trennräume ist.

Kann mir jemand in die richtige Richtung zeigen?

Antwort

3

Strategie Ich empfehle:

  1. Lesen Sie die Datei Zeile für Zeile std::getline verwenden.
  2. Suchen Sie in der Zeile mit nach der Zeichenfolge, die Sie ersetzen möchten.
  3. Wenn es gefunden wird, ersetzen Sie es durch die neue Zeichenfolge.
  4. Wiederholen Sie die Schritte 2 und 3, bis die Zeichenfolge nicht gefunden wird.
  5. Ausgabe der aktualisierten Zeile.

Hier ist der Kern-Code dafür:

while (getline(openningTheFile, line)) 
{ 
    std::string::size_type pos; 
    while ((pos = line.find(wordToBeDeleted)) != std::string::npos) 
    { 
     line.replace(pos, wordToBeDeleted.length(), wordToReplaceWith); 
    } 
    newFile << line << '\n'; 
} 
+1

Beste Antwort bisher, weil diese Methode alle Leerzeichen erhält. –

+1

Sie können Deklarationen nicht innerhalb von Ausdrücken platzieren. –

+0

@yurikilochek, danke für den Hinweis auf den Fehler. –

0

Sie lesen eine Zeile des Textes mit std::getline.

Sie müssen das Wort innerhalb der Textzeile finden, das Wort ersetzen und dann die Textzeile in die Ausgabedatei schreiben. Eine Methode besteht darin, std::stringstream und den Operator >> zu verwenden, um das Wort aus der Zeichenfolge zu extrahieren.

Eine andere ist zu verwenden std::string::find, um die Position des Wortes zu lokalisieren.

+0

ist es möglich für Sie zu erweitern, wie Stringstream zu verwenden, um das Wort aus der Zeichenfolge zu extrahieren und es ersetzt haben? – mohsen

+0

@mohsen Das ist in meinem Beitrag beantwortet. Müssen Sie auch die Whitespaces erhalten? –

+0

@ πάνταῥεῖ Ich brauche die neue Datei erstellt, um genau das Wort zu sein, das geändert wurde – mohsen

0

können Sie tun, dass die Schleife durch Modifizieren wortweise von der Linie std::istringstream lesen mit zu lesen:

while (getline(openningTheFile, line)) 
{ 
    std::istringstream iss(line); 
    std::string word; 
    bool firstWord = true; 
    while(iss >> word) 
    { 
     if(word == wordToBeDeleted) { 
      newFile << wordToReplaceWith; 
      if(!firstWord) { 
       newFile << " "; 
      } 
      firstWord = false; 
     } 
    } 
    newFile << `\n`; 
} 
+0

Würde dies nicht löschen alle Leerzeichen zwischen den Wörtern in der Ausgabe? – zett42

+0

@ zett42 Hoppla, ja. –

+0

Nun werden benachbarte ws in der Eingabe zu einzelnen ws in Ausgabe zusammengeführt. Ziemlich destruktiv noch ;-) – zett42

0

Hier ist eine Lösung, die die Macht von boost::iostreams verwendet die Aufgabe in einem hohen Niveau zu lösen, aber immer noch sehr flexibel.

Für OPs Fall ist dies wahrscheinlich wie mit einem Vorschlaghammer, um eine Nuss zu knacken, aber wenn man Flexibilität braucht oder mit komplexeren Fällen umgehen muss, könnte es das richtige Werkzeug sein.

Ich verwende eine filtering stream kombiniert mit einer regular expression. Dies ermöglicht es uns, ein Suchmuster im laufenden Betrieb durch eine Ersatzzeichenfolge zu ersetzen, ohne eine Zwischenzeichenfolge zu erzeugen.

#include <iostream> 
#include <string> 
#include <sstream> 
#include <boost/iostreams/filtering_stream.hpp> 
#include <boost/iostreams/filter/regex.hpp> 
#include <boost/iostreams/copy.hpp> 
#include <boost/regex.hpp> 
namespace io = boost::iostreams; 
using namespace std; 

int main() 
{ 
    // Your input "file" - you may replace it by an std::ifstream object. 
    istringstream in("why waste time learning learninglearning, when ignorance is instantaneous?"); 

    // Search pattern and substitution string.   
    string findRegEx(R"(\blearning\b)"); 
    string replaceStr("sleeping"); 

    // Build a regular expression filter and attach it to the input stream. 
    io::filtering_istream inFiltered; 
    inFiltered.push(io::regex_filter(boost::regex(findRegEx), replaceStr)); 
    inFiltered.push(in); 

    // Copy the filtered input to the output, replacing the search word on-the-fly. 
    // Replace "cout" by your output file, e. g. an std::ofstream object. 
    io::copy(inFiltered, cout); 

    cout << endl; 
} 

Live demo

Ausgang:

why waste time sleeping learninglearning, when ignorance is instantaneous? 

Hinweise:

  • Die tatsächliche regulärer Ausdruck ist \blearning\b
  • Wir müssen den Backslash nicht umgehen, weil wir eine raw string literal verwenden. Sehr ordentlich für solche Sachen. Der reguläre Ausdruck sucht nach dem ganzen Wort "Lernen" (\b bezeichnet eine Wortgrenze). Deshalb ersetzt es nur das erste Vorkommen von "Lernen" und nicht "Lernenlernen".
Verwandte Themen