2010-11-19 4 views
1

J'ai rencontré un problème vraiment étrange. Je peux reproduire sur mon portable win7 ainsi que sur une machine ubuntu.Les nombres de C++ cin ignorent la première ligne?

J'ai un programme C++ comme ceci:

#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; 
} 

Maintenant, si je le compiler une course avec ./a.out < test.txttext.txt contient:

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 

Il sortira (sans espaces):

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 

Pourquoi la première ligne est-elle incorrecte? J'ai aussi essayé de lire la première ligne de la boucle. En outre, si je remplace ss > p avec cin > p je viens d'obtenir une table de sortie pleine de 8.

Cela n'a aucun sens !!

D'accord, vous aviez raison. Certains trucs bizarres comme le premier caractère de mon fichier d'entrée:

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

Peut-être qu'il y a quelque chose de génial dans votre fichier 'test.txt' - peut-être le regarder avec un éditeur hexadécimal? J'obtiens le contenu de 'test.txt' (sans espaces) en écho quand je compile/cours avec GCC 4.5.1 (MinGW) ou avec VS2010. –

+0

Je pense qu'il y a une ligne vide au début de votre test.txt (ou quelque chose qui n'est pas numérique). –

+0

les chaînes de format sont meilleures! – Svisstack

Répondre

1

C'est un problème avec les données (puisque le code semble correct). Vous avez probablement enregistré votre fichier texte avec l'encodage UTF-8 avec BOM. Une nomenclature UTF-8 est trois octets au début du fichier, et essayant de les interpréter comme une spécification de nombre décimal échouerait.

Deuxième, troisième, quatrième ligne, etc. OK, car vous créez un nouvel objet istringstream pour chaque ligne, afin de ne pas conserver le mode d'erreur de la ligne précédente. Donc, correction: enregistrez le fichier sans nomenclature - en supposant que l'hypothèse de nomenclature est correcte.

Vive & HTH.,

0

Votre code me semble bien, si j'étais vous, je vérifier deux fois fichier d'entrée: êtes-vous sûr qu'il n'y a pas première ligne vide, ou un caractère non numérique au début de la ligne 1?

0

je soupçonne que vous avez écrit votre propre getline(), et le bug est là. InputStreams ont un getline(char*, int), et je soupçonne votre bachotage string.begin() dans le premier param, et un autre nombre dans le dernier.

Ne faites pas cela.

Tout ce que votre programme devrait faire est de copier l'entrée à la sortie (étant donné ce code et cette entrée). Ce n'est pas non plus le cas, même sur les lignes qui «fonctionnent».

Je vois un certain nombre de 'signatures' de programmeurs si peu expérimentés ici. 1) Noms de variables trop courts (en dehors d'un compteur de boucle for), "ss" et "p" 2) Numéro d'erreur magique (8), en particulier un qui ne ressort pas des données. 3) "using"

1 et 3 indiquent tous les deux un manque de vitesse de frappe, et donc l'expérience ... malgré votre réputation 1k + (qui repose principalement sur des questions ... la situation devient plus claire).

Je réécris quelque chose comme ceci:

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

Les chances sont, vous allez voir « ECHEC à la ligne: 0 contenant: » à droite de la porte, en raison de ce que je pense est un bug dans votre getline().

Questions connexes