2010-07-30 32 views
3

Ceci est le texte de mon programme:C++ pourquoi ai-je seulement la dernière ligne?

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

int main(){ 
    string line; 
    ifstream inf("grid.txt"); 
    while(!inf.eof()){ 
     getline(inf, line); 
     cout << line; 
    } 
    return 0; 
} 

(je vais utiliser sstream plus tard)

Ceci est le contenu de grid.txt:

08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 

Je compile ce sous Cygwin et g ++ et voici ce que je reçois:

$ g++ program.cpp 
$ ./a.exe 
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 

Pour sauvez-vous - c'est la dernière ligne du fichier. Si je remplace la boucle avec:

getline(inf, line); 
cout << line; 
getline(inf, line); 
cout << line; 

il affichera pas le premier, mais la deuxième ligne du fichier. Cela fait longtemps que je n'ai pas programmé en C++, mais je suis sûr à 90% qu'il est censé afficher plus d'une ligne ...

+0

Cela fonctionne parfaitement pour moi (en utilisant g ++ sous Fedora). – nico

+1

Fonctionne pour moi. Cependant, vous devriez écrire 'while (getline (...))'. Notez également que 'line' n'inclut pas le séparateur de ligne lui-même, vous devriez donc écrire' cout << line << endl; '. – Philipp

+1

@Philipp - "ligne" ne comprend pas le séparateur de ligne lui-même - bingo. Il sort chaque ligne, mais chaque ligne écrase la précédente car il y en a \ r mais pas \ n ... Cygwin a aussi un peu de magie pour améliorer les fins de ligne du fichier texte. – jmanning2k

Répondre

6

Essayez d'ajouter un std::endl, qui ajoutera automatiquement une nouvelle ligne et videra le tampon .

Vous pouvez également utiliser la signature istream& getline (istream& is, string& str, char delim); pour spécifier un autre délimiteur que la valeur par défaut qui est le retour à la ligne si votre fichier n'en possède pas.

2

Vous n'émettez pas de retour à la ligne à la fin des lignes, elles s'interpénètrent donc mutuellement.

Modifiez la ligne de sortie

cout << line << endl; 
+0

Pourquoi les lignes se remplaceraient-elles? Ils devraient juste être écrits comme une longue ligne. C'est la sortie produite par le code OP sur VS2008. – Praetorian

+0

@Prae, car il produit des retours chariot mais pas de retour chariot. Je ne sais pas si c'est parce que le fichier est écrit de cette façon, ou si quelque chose avale les nouvelles lignes. –

+0

oui, si le fichier a des terminaisons de ligne '\ r'' getline() 'est en train de lire le tout en une seule ligne, incluant tous les' \ r'.Ensuite, lorsque vous l'imprimez sur le terminal, il revient au début de la ligne chaque fois qu'il voit un '\ r'. Vous avez donc raison sur la partie écrasement, mais votre solution ne fonctionnera pas car au moment où vous imprimez cette 'endl', le dommage est déjà fait. – Praetorian

-1

Vous êtes en train de lire des données binaires en utilisant getline. Essayez d'utiliser read() à la place.

+0

Ce ne sont pas des données binaires, ce sont des chiffres –

+0

N'est-ce pas un vidage hexadécimal? Désolé, mon erreur – Jay

4

De quel format de fichier est votre grid.txt? Il est probable que vos lignes se terminent par un retour chariot \r

Tout comme je fini de poser ma question, j'ai essayé:

cout << "hi"; 

avant de le changer pour les deux cout s. Quand j'ai eu deux caractères supplémentaires, c'est quand j'ai réalisé que je recevais le personnage \r. (Pouvez-vous dire que j'ai déjà rencontré des problèmes avec le retour chariot?: P)

+0

Je pense que vous avez la bonne réponse. Je viens de créer un fichier texte avec des terminaisons de ligne '\ r' et le code imprime juste la dernière ligne. – Praetorian

+1

En effet. Cygwin/g ++ assumera les fins de ligne de type Unix (juste '\ n'), mais si vous avez créé le fichier sous Windows, il pourrait contenir des caractères' \ r' pour la compatibilité avec les machines à écrire manuelles. –

+0

J'ai été mordu par le '\ r' quand je faisais de l'exploration de données pour mon projet final CSCI 2. C'était plus facile à voir alors parce que les lignes n'étaient pas de la même longueur, mais c'était pire parce que je n'avais aucune idée de ce que char (13)/retour de chariot était. OTOH, cr sont terriblement utiles si vous voulez une seule ligne de données changeantes. J'en ai beaucoup utilisé dans ma classe d'assemblage^_ ^ –