2010-11-19 15 views
1

Ich bin auf ein wirklich seltsames Problem gestoßen. Ich kann auf meinem win7 Laptop sowie einem ubuntu Rechner reproduzieren.C++ cin Zahlen ignoriert die erste Zeile?

Ich habe ein C++ Programm wie folgt:

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

int main() { 
    for (int i = 0; i < 9; i++) { 
    string line; 
    getline(cin, line); 
    stringstream ss(line); 

    for (int j = 0; j < 9; j++) { 
     int p = 8; 
     ss >> p; 
     cout << p; 
    } 
    cout << endl; 
    } 
    return 0; 
} 

Nun, wenn ich es ein Lauf mit ./a.out < test.txt kompilieren, wo text.txt enthält:

1 2 3 4 5 6 7 8 9 
2 2 3 4 5 6 7 8 9 
3 2 3 4 5 6 7 8 9 
4 2 3 4 5 6 7 8 9 
5 2 3 4 5 6 7 8 9 
6 2 3 4 5 6 7 8 9 
7 2 3 4 5 6 7 8 9 
8 2 3 4 5 6 7 8 9 
9 2 3 4 5 6 7 8 9 

Es wird ausgegeben (ohne Leerzeichen):

8 8 8 8 8 8 8 8 8 
2 2 3 4 5 6 7 8 9 
3 2 3 4 5 6 7 8 9 
4 2 3 4 5 6 7 8 9 
5 2 3 4 5 6 7 8 9 
6 2 3 4 5 6 7 8 9 
7 2 3 4 5 6 7 8 9 
8 2 3 4 5 6 7 8 9 
9 2 3 4 5 6 7 8 9 

Warum ist die erste Zeile falsch? Ich habe versucht, auch die erste Zeile aus der Schleife zu lesen. Auch, wenn ich ss > p durch cin > p ersetze, bekomme ich nur eine Ausgabetabelle voller 8.

Das ergibt keinen Sinn !!

Okay, ihr habt recht gehabt. Einige seltsame Dinge als erstes Zeichen meiner Eingabedatei:

od -c test.txt 
0000000 357 273 277 2  0  5  0  0  7  0 
0000020  0  6 \n 4  0  0  9  6  0 
0000040  0  2  0 \n 0  0  0  0  8 
+1

Vielleicht gibt es etwas funky in Ihrer 'test.txt' Datei - vielleicht mit einem Hex-Editor? Ich bekomme den Inhalt von 'test.txt' (ohne Leerzeichen), wenn ich mit GCC 4.5.1 (MinGW) oder mit VS2010 kompiliere/laufe. –

+0

Ich denke, es ist eine leere Zeile am Anfang Ihrer test.txt (oder etwas, das nicht numerisch ist). –

+0

Formatzeichen sind besser! – Svisstack

Antwort

1

Es ist ein Problem mit den Daten (da der Code OK aussieht). Höchstwahrscheinlich haben Sie Ihre Textdatei mit UTF-8-Codierung mit BOM gespeichert. Eine UTF-8-Stückliste besteht aus drei Bytes am Anfang der Datei und der Versuch, diese als Dezimalzahlspezifikation zu interpretieren, würde fehlschlagen.

Zweite, dritte, vierte Zeile usw. OK, weil Sie für jede Zeile ein neues istringstream Objekt erstellen, sodass der Fehlermodus der vorherigen Zeile nicht beibehalten wird.

Fix: Speichern Sie die Datei ohne BOM - vorausgesetzt, die BOM-Hypothese ist korrekt.

Beifall & hth.,

0

Ihr Code scheint mir gut, wenn ich Sie wäre ich verdoppeln würde die Eingabedatei überprüfen: Sind Sie sicher, dass es keine leere erste Zeile oder ein nicht-numerisches Zeichen am Anfang von Zeile 1?

0

Ich vermute, dass Sie Ihre eigenen getline(), und der Fehler ist, schrieb dort. InputStreams haben eine getline(char*, int), und ich vermute, dass Sie Ihre string.begin() in den ersten Param und Some Other Number in die letztere param.

Tun Sie das nicht.

Alles, was Ihr Programm tun sollte, ist das Kopieren der Eingabe in den Ausgang (mit diesem Code und diesem Eingang). Das tut es auch nicht, selbst in den Zeilen, die "funktionieren".

Ich sehe eine Reihe von nicht so erfahrenen Programmierer 'Signaturen' hier. 1) Zu kurze Variablennamen (außerhalb eines For-Loop-Zählers), "ss" und "p" 2) Magische Fehlernummer (8), insbesondere eine, die sich nicht von den Daten abhebt.

1 und 3 deuten beide auf einen Mangel an Schreibgeschwindigkeit, und damit Erfahrung ... trotz Ihrer 1k + Reputation (die vor allem auf Fragen basiert ... die Situation wird klarer).

ich es so etwas wie dies umschreiben würde:

int curDig; 
curLine >> curDig; 
if (curLine.good()) { 
    cout << curDig; 
} else { 
    cout << "FAILED at line: " << lineIdx << " containing: " << line << std::endl; 
} 

Die Chancen stehen gut, Sie gehen „FAILED in Zeile: 0 enthält:“ um zu sehen, rechts aus dem Tor, durch das, was ich denke, ist ein Fehler in Ihrem getline().