2010-08-18 4 views
2

Pour simplifier, j'essaie de lire le contenu d'un fichier CSV en utilisant la classe ifstream et sa fonction membre getline(). Voici ce CSV fichier:Comportement inattendu de getline() avec ifstream

1,2,3 
4,5,6 

Et le code:

#include <iostream> 
#include <typeinfo> 
#include <fstream> 

using namespace std; 

int main() { 
    char csvLoc[] = "/the_CSV_file_localization/"; 
    ifstream csvFile; 
    csvFile.open(csvLoc, ifstream::in); 
    char pStock[5]; //we use a 5-char array just to get rid of unexpected 
        //size problems, even though each number is of size 1 
    int i =1; //this will be helpful for the diagnostic 
    while(csvFile.eof() == 0) { 
     csvFile.getline(pStock,5,','); 
     cout << "Iteration number " << i << endl; 
     cout << *pStock<<endl; 
     i++; 
    } 
    return 0; 
} 

J'attends tous les chiffres à lire, car getline est supposé prendre ce qui est écrit depuis la dernière lecture, et d'arrêter en rencontrant ',' ou '\ n'.

Mais il semble qu'il lit tout bien, sauf « 4 », à savoir le premier numéro de la deuxième ligne (console voir):

Iteration number 1 
1 
Iteration number 2 
2 
Iteration number 3 
3 
Iteration number 4 
5 
Iteration number 5 
6 

Ainsi ma question: ce qui fait de cette « 4 » après (Je suppose) le '\ n' si spécifique que getline n'essaie même pas de le prendre en compte?

(Merci!)

Répondre

6

Vous lisez des valeurs séparées par des virgules si vous lisez en séquence: 1, 2, 3\n4, 5, 6.

Vous pouvez ensuite imprimer le premier caractère du tableau à chaque fois: à savoir 1, 2, 3, 5, 6.

Qu'attendiez-vous? Incidemment, votre chèque pour eof est au mauvais endroit. Vous devez vérifier si l'appel getline aboutit. Dans votre cas, cela ne fait pas de différence car getline lit quelque chose et déclenche EOF en une seule action mais en général il peut échouer sans rien lire et votre boucle en cours traitera pStock comme si elle avait été repopulée avec succès.

Plus généralement quelque chose comme ça serait mieux:

while (csvFile.getline(pStock,5,',')) { 
    cout << "Iteration number " << i << endl; 
    cout << *pStock<<endl; 
    i++; 
} 
+0

"Qu'attendiez-vous?" En fait, si je regarde http://www.cplusplus.com/reference/iostream/istream/getline/, il me semble que getline agit avec '\ n' tout comme il agit avec le délimiteur spécifié. A savoir, s'arrêter juste pour lire quand il est rencontré (ainsi, tout comme avec "1,2" il s'arrête avant 2, avec "3 \ n4" il aurait dû s'arrêter avant 4). Mais je suppose que ce n'est pas le cas, moi que je ne comprends pas tout bien! Merci pour la réponse. – Kamixave

+0

@Kamixave: Avec ma lecture de cplusplus.com, je ne pense pas que ce soit incorrect.'\ n' est juste le délimiteur par défaut si vous n'en fournissez pas. Si vous en fournissez un, il est utilisé à la place (pas aussi bien). –

+0

@Charles Bailey: Pouvez-vous s'il vous plaît ajouter l'exemple std :: getline (, ). Cette version a un potentiel de dépassement de tampon. –

3

si vous utilisez AFAIK le paramètre de terminaison, getline() lit jusqu'à ce qu'il trouve le séparateur. Ce qui signifie que dans votre cas, il a lu

3\n4 

dans le tableau pSock, mais vous n'imprimer le premier caractère, vous obtenez 3 seulement.

1

le problème avec votre code est que getline, lorsqu'un délimiteur est spécifié, ', dans votre cas, utilise et ne tient pas compte du délimiteur par défaut' \ n '. Si vous souhaitez analyser ce fichier, vous pouvez utiliser une fonction de tokenisation.

Questions connexes