2016-05-01 6 views
3

Ich möchte Zeilen aus einer Textdatei lesen, die das folgende Format haben: a r3, r2, r1 und ich möchte dies in einzelne Teile aufteilen, so habe ich eine Variable, die a, r3, r2 und enthält r1 einzeln, also muss ich den whitespace und das Komma entfernen. Ich bin mir nicht sicher, wie ich das machen soll. Ich habe gesucht um, kann aber nur Beispiele (wie this) mit vordefinierten Zeichenkette finden.Parsing und Split von einer Textdatei

Ich weiß, wie in einem Text aus einer Datei und legen Sie sie in ein char-Array zu lesen, aber ich würde im Idealfall jedes Element einer Zeile in eine eigene Variable platzieren möchten.

So etwas wie:

#include <iostream> 
#include <string> 
#include <fstream> 
using namespace std; 

void main() 
{ 
    string var1, var2, var3, var4; 
    ifstream inFile("myfile.txt"); 

    if (inFile.is_open()){ 
     while (!inFile.eof()){ 
     inFile >> var1 >> var2 >> var3 >> var4; 
     } 
    } 
} 

aber wo es behandelt Leerzeichen, Kommas und neue Linien. Irgendwelche Vorschläge, wie man das macht?

+1

Zu allererst [tun dies nicht: 'while (! InFile.eof())'] (https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside- a-loop-bedingung-als falsch angesehen. – WhozCraig

+0

'string.replace()?' Komma durch leere-ness. Oder noch besser 'string.erase()' das Komma. 'string.pop_back()' das letzte Zeichen? –

Antwort

1

Sie eine Zeile mit std::getline(<stream>, <string>) lesen kann.

std::string line; 
while(std::getline(inFile, line)) 
{ 
    // You successfully read a line. 
} 

Es gibt tatsächlich einen dritten Parameter std::getline(), die das Ende der Linie angibt. Standardmäßig ist dies '\ n', aber Sie geben Ihr Online-Ende an (das wäre ',').

std::stringstream lineStream(line); // convert your line into a stream. 

if (std::getline(lineStream, a, ',') && 
    std::getline(lineStream, r1, ',') && 
    std::getline(lineStream, r2, ',') && 
    std::getline(lineStream, r3, ',') 
    ) 
{ 
    // Read all the values successfully 
} 

Wenn Sie Linie durch Raum operator>> die Verwendung aufgebrochen wird, statt std::getline().

std::stringstream lineStream(line); // convert your line into a stream. 

if (lineStream >> a >> r1 >> r2 >> r3) 
{ 
    // Read all the values successfully 
} 
+0

Ich bin nicht sicher, ich folge, was Sie mit dem Online-Ende ',' meinen. Wenn meine Zeile ein (Leerzeichen) ra, ra, rc ist, gibt es kein Zeilenende mit Ausnahme von \ n, das gelesen würde. – Noobgineer

+0

Der dritte Parameter von 'std :: getline()' ist das Zeichen, bei dem das Lesen beendet wird. Standardmäßig stoppt es bei ''\ n'', aber Sie können jedes andere Zeichen (wie'', '') verwenden. Wenn Ihre Wörter a Leerzeichen getrennt sind, benutzen Sie 'operator >>' –

+0

meine Zeile ist mit Leerzeichen und Kommas wie in der Frage gezeigt: a (Leerzeichen) r1, (Leerzeichen) r2, (Leerzeichen) r3 \ n – Noobgineer

0

nicht die eleganteste Lösung jedoch etwas in diese Richtung arbeiten:

void parse_input(const std::string& _buffer, std::string& _s1, std::string& _s2, 
std::string& _s3, std::string& _s4); 

int main(void) { 
    std::ifstream inFile("foo.txt"); 

    std::string var1, var2, var3, var4; 
    std::string buffer = ""; 
    while(std::getline(inFile, buffer)) { 
     parse_input(buffer, var1, var2, var3, var4); 
    } 
} 

void parse_input(const std::string& _buffer, std::string& _s1, std::string& _s2, 
std::string& _s3, std::string& _s4) { 
    size_t count = 0; 
    // increment count until first space char 
    while (buffer.at(count) != ' ') { 
     ++count; 
    } 
    // set _s1 to substring of _buffer from start to first space 
    _s1 = _buffer.substr(0, count); 
    size_t prev_count = count; 
    // repeat above for comma char instead... 
    while (buffer.at(count) != ',') { 
     ++count; 
    } 
    _s2 = _buffer.substr(prev_count, count); 
    prev_count = count; 
    while (buffer.at(count) != ',') { 
     ++count; 
    } 
    _s3 = _buffer.substr(prev_count, count); 
    prev_count = count; 
    while (buffer.at(count) != ',') { 
     ++count; 
    } 
    _s4 = _buffer.substr(prev_count, count); 
} 

Beachten Sie, dass dies nicht Index in dem _buffer Argumente von parse_input außerhalb der Grenzen Fehler nicht verhindern - Sie zusätzliche Prüfungen hinzufügen müßten in den Schleifen while wie && count < _buffer.size().

1

Alle unten Möglichkeiten arbeiten für Ihren Fall:

Sie solche Routine für jede Zeichenfolge verwenden können. Überprüfen Sie, ob das letzte Zeichen ein Komma ist. wenn ja, ersetzen Sie ihn durch „leer-ness“:

if (var1[var1.size() - 1] == ',') 
    var1.replace(var1.size() - 1, var1.size() - 1, ""); // (From index, to index, with) 

können Sie pop_back() das letzte Zeichen, wenn es ein Komma ist:

if (var2[var2.size() - 1] == ',') 
    var2.pop_back(); 

Sie können aber auch einfach das Komma löschen, wenn es ist das letzte Zeichen:

if (var3[var3.size() - 1] == ',') 
    var3.erase(var3.size() - 1, var3.size() - 1); // (From index, to index) 
+0

Handelt es sich um Leerzeichen? – Noobgineer

+0

@noobgineer 'inFile >> var1' ignoriert Leerzeichen standardmäßig –

+0

Was passiert, wenn ich eine andere Anzahl von Variablen hat, so läßt man sagen Linie hatte nur drei Elemente oder ein anderes besteht aus 5 Elementen, würde ich erklären, nur die maximale Anzahl der Variablen i brauchen und sich nicht sorgen, dass Var5 nichts liest? – Noobgineer