2016-04-17 7 views
1

Ich habe dieses „data.txt“ mit diesem Text innen:Wie ersetzt man Text einer bestimmten Zeile in einer TXT-Datei durch Qt?

1;Bob;Patino;43 
/2;Chris;Metsen;46 
/3;Rob;Pardo;37 
/4;Megan;Fox;25 
/5;Cara;Delevingne;21 

Und ich möchte den Text der zweiten Zeile „Metsen“ für „Metzen“ ersetzen. Ich kann es tun, indem ich die ganzen Daten umschreibe und es wäre einfach, aber möglicherweise nicht bequem für Tonnen von Daten.

Gibt es eine Möglichkeit, dies zu tun, indem nur diese spezifischen Daten überschrieben werden (idealerweise mit QFile und QTextStream)?

+0

Nun, in diesem speziellen Fall können Sie nur auf den s suchen und az an seiner Stelle schreiben, aber in einem beliebigen Ersatz-Szenario wird es nicht so einfach sein, dazu gibt es Textcodierung ist es nicht ein Raw-Byte-Array, so dass Sie wahrscheinlich die gesamte Datei in eine Zeichenkette einlesen müssen, irgendwelche Ersetzungen vornehmen und dann die Datei neu schreiben müssen. – dtech

+0

'QRegExp' könnte dein Freund sein. –

+0

@NicolasHolthaus können Sie es beispielsweise auf QFile und QTextStream anwenden? –

Antwort

2

Es klingt von Ihrer Frage, dass Sie die Ersetzung in Memory-mapped IO, die im allgemeinen Fall nicht möglich ist, tun möchten. Was passiert, wenn die Datei nicht ASCII-codiert ist oder wenn der Ersatztext nicht dieselbe Größe wie der Text hat, der ersetzt wird? Sobald Sie eine 'Einfügen'-Operation benötigen, schreiben Sie die gesamte Datei neu, ob Sie es möchten oder nicht. Darüber hinaus muss die Datei immer noch vollständig lesen, um den Text zu suchen, so dass es am Ende sowieso nicht viel von einer Optimierung sein würde. Moderne Diskettenlaufwerke haben Schreibgeschwindigkeiten von Hunderten bis Tausenden von Megabytes pro Sekunde, so dass Ihre Schreibzeit wahrscheinlich vernachlässigbar ist.

Ganz zu schweigen davon, dass Sie fast 100% Ihre ursprünglichen Daten beschädigen werden, während Sie versuchen, das Programm zu debuggen. Selbst wenn Sie es richtig machen, würden Sie die ursprünglichen Daten auch beschädigen, wenn der Prozess zum Erliegen käme. Es ist nicht der richtige Ansatz.

Das heißt, einfache Teilzeichenfolge Ersatz kann mit QFile und QTextStream mit regulären Ausdrücken durchgeführt werden. Dieses Programm liest data.txt ein, korrigiert die Rechtschreibfehler und schreibt die Ergebnisse in eine neue Datei namens .

#include <QFile> 
#include <QRegularExpression> 
#include <QRegularExpressionMatch> 
#include <QRegularExpressionMatchIterator> 
#include <QTextStream> 

int main(int argc, char *argv[]) 
{ 
    QFile data("C:/workspace/simpleQtProject/data.txt"); 
    data.open(QIODevice::Text | QIODevice::ReadOnly); 
    QString dataText = data.readAll(); 

    QRegularExpression re("Metsen"); 
    QString replacementText("Metzen"); 

    dataText.replace(re, replacementText); 

    QFile newData("C:/workspace/simpleQtProject/newData.txt"); 
    if(newData.open(QFile::WriteOnly | QFile::Truncate)) { 
     QTextStream out(&newData); 
     out << dataText; 
    } 
    newData.close(); 

    return 0; 
} 

Hinweis: Optimierte Leistung von QRegularExpression ist eigentlich wirklich gut, aber kann Debugging aufgrund der JIT-Compiler langsam wird im Debug-Modus deaktiviert. Eine gute Diskussion über die Nuancen der Implementierung (und Benchmarks der Release-Leistung) finden Sie unter peppe's blog post.

Wenn Ihre Regexs komplexer werden und Sie eine feinere Kontrolle darüber benötigen, wie die Ersetzungen durchgeführt werden, können Sie die QRegularExpressionMatchIterator-Syntax und die indexbasierte QString::replace() verwenden. Dies könnte mehrere oder benannte Erfassungsgruppen oder andere erweiterte Regex-Funktionen unterstützen.

#include <QFile> 
#include <QRegularExpression> 
#include <QRegularExpressionMatch> 
#include <QRegularExpressionMatchIterator> 
#include <QTextStream> 

int main(int argc, char *argv[]) 
{ 
    QFile data("C:/workspace/simpleQtProject/data.txt"); 
    data.open(QIODevice::Text | QIODevice::ReadOnly); 
    QString dataText = data.readAll(); 

    // Using regex match iterator. Overkill for simple substring replacement, but scalable 
    // to very complex replacements. 
    QRegularExpression re("Metsen"); 
    QString replacementText("Metzen"); 

    QRegularExpressionMatchIterator itr = re.globalMatch(dataText); 

    while(itr.hasNext()) 
    { 
     QRegularExpressionMatch match = itr.next(); 
     dataText.replace(match.capturedStart(0), match.capturedLength(0), replacementText); 
    } 

    QFile newData("C:/workspace/simpleQtProject/newData.txt"); 
    if(newData.open(QFile::WriteOnly | QFile::Truncate)) { 
     QTextStream out(&newData); 
     out << dataText; 
    } 
    newData.close(); 

    return 0; 
} 
+1

Vielen Dank für die Erklärung und für die Klärung meines Problems. Die zweite Lösung hilft mir sehr bei meinem Projekt, ty so viel auch dafür. –

+0

froh, um zu helfen. –

Verwandte Themen