2016-10-10 5 views
0

Ich arbeite am Einlesen von einer Datei und Parsing durch Daten aus Kommandozeilenargument für die Hausaufgaben. Und ich rannte in eine Wand und ich weiß nicht, was das Problem ist, und ich hoffe, ich könnte einen Rat bekommen, was ich vermisse.Einlesen von Datei gibt unerwartete Ausgabe

Die Datendatei ist so zusammengesetzt; in der ersten Zeile hat es die Anzahl der gesamten Zeilen. Für jede Zeile danach ist es eine Zeichenfolge, die durch | getrennt wird Charakter. Ich brauche das '|' Zeichen, weil ich meinen String in Teilstrings aufteilen möchte.

Hier ist ein Beispiel für eine Eingabedatei.

3 
league of legends|Teemo|Master Yi|Vayne 
apple|samsung|smart phone|smart watch 
overwatch|d.va|junkrat|Reinhart 

Hier ist mein Code.

int main(int argc, char* const argv[]) 
{ 

//change string to char* so I can check through each char to see if the 
//thing I read in is '|' character. 
String Data = (argv[1]); 
ifstream fin (Data.c_str()); 

//check whether the file is open. 
if (!fin.is_open()) 
{ 
    cout << "Could not open file" << endl; 
} 

else 
{ 
    int dataLines; 
    char dataBuffer[100]; 

    //The first integer I read in will be how many lines I will loop through 
    fin >> dataLines; 
    //ignore the new line character and do not include it in the count of 
    //dataLines. 
    fin.ignore(); 

    //use noskipws so I can recognize whitespaces. 
    fin >> noskipws >> dataBuffer; 

    //TEST CODE: COMMENTED OUT FOR NOW. 
    //cout<<dataBuffer<<endl; 

    //loop for the number of lines 
    for(int i = 0; i < dataLines; i++) 
    { 

     fin.getline(dataBuffer, 100); 
     //print the buffer for checking 
     cout<<dataBuffer<<endl; 
    } 
} 
//close the file. 
fin.close(); 
return 0; 

}

Das Ergebnis soll wie folgt aussehen.

league of legends|Teemo|Master Yi|Vayne 
apple|samsung|smart phone|smart watch 
overwatch|d.va|junkrat|Reinhart 

Das tatsächliche Ergebnis sieht wie folgt aus

of legends|Teemo|Master Yi|Vayne 
apple|samsung|smart phone|smart watch 
overwatch|d.va|junkrat|Reinhart 

Das erste Wort, das ich in gelesen aus dem Puffer ist weg. "Liga" ist die fehlende, und ich habe versucht, das Problem zu erkennen, indem ich den Testcode an der Stelle einfüge, die in meinem Code angegeben ist. Mit dem gegebenen Testcode, meine Ausgabe ist

league 
of legends|Teemo|Master Yi|Vayne 
apple|samsung|smart phone|smart watch 
overwatch|d.va|junkrat|Reinhart 

Das Problem ist also, dass mit noskipws in die Datei zwischen Lesen und dem forloop, die über Datenleitungsschleifen. Vor dem Forloop ist mein Puffer Liga. Doch sobald ich die Schleife betrete, wird diese übergeben und geht direkt zu von.

Was fehlt mir hier? Was könnte eine mögliche Lösung sein?

Antwort

0

Sie brauchen nicht die folgende Zeile:

fin >> noskipws >> dataBuffer; 

mit g getestet ++ 4.8.3 2 auf RHEL 7.1

+1

Korrekt. Aber warum sollte es wirklich nützlich sein? – user4581301

1

Hauptproblem:

fin >> noskipws >> dataBuffer; 

macht zwei Dinge. 1. >> noskipws schaltet automatisch überspringt Whitespace, unnötig, weil OP den Stream liest. 2. >> dataBuffer liest das erste Wort aus dem Stream, in diesem Fall verbraucht das Wort "Liga"

Lösung: Tun Sie dies nicht.

Andere Probleme:

fin.ignore(); 

ignoriert genau ein Zeichen. Aber was, wenn jemand nach der Zählung einen fast unsichtbaren Raum hinterließ? Verwenden Sie stattdessen

fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

um sicherzustellen, dass der Rest der Zeile in seiner Gesamtheit konsumiert wird.

char dataBuffer[100]; 

Warum sich leiden lassen? Stattdessen verwenden

std::string dataBuffer; 

Empfehlung:

Verwenden std::stringstream und std::getline die Linien tokenize auf '|'

+0

Vielen Dank für die Hilfe! Ich habe die Noskipws los und das Problem ist gelöst. Ich kann weitermachen! –

+0

Auch die while (getline (stream, token, '| ")) Schleife trennt die Daten durch' | '. Viel kürzer und einfacher zu verstehen als das, was ich getan habe. Nochmals vielen Dank für Ihre Zeit und Hilfe! –

0

Vielen Dank Benutzer 4581301. Es liest die Daten korrekt ein Charakter. Jetzt kann ich daran arbeiten, die Daten in Klassen zu speichern.

für alle, die dasselbe Problem haben können, ist dies die behobene Version des Codes.

int main(int argc, char* const argv[]) 
{ 

String Data = (argv[1]); 
ifstream fin (Data.c_str()); 

if (!fin.is_open()) 
{ 
    cout << "Could not open file" << endl; 
} 

else 
{ 
    int dataLines; 
    char dataBuffer[100]; 

    fin >> dataLines; 
    fin.ignore(); 

    for(int i = 0; i < dataLines; i++) 
    { 
     while(fin.getline(dataBuffer, 100, '|')) 
     { 
      cout<<dataBuffer<<endl;// check to see if it reads in correctly. 
     } 
    } 
} 
fin.close(); 
return 0; 
}