2010-08-22 4 views
3

Je lis les données d'un fichier dans un vecteur de chaînes appelé data. Et à ce vecteur de données je push_back une nouvelle chaîne à travers mon principal appelé output_string. Output_string est juste une combinaison des arguments passés dans la ligne de commande. Après avoir fait tout ce que je réécris dans mon fichier (mettre à jour le fichier avec la nouvelle chaîne). Cependant quand je fais ceci, tout après le premier argument de ligne de commande, il saute une position de vecteur chaque fois qu'il rencontre à nouveau data.push_back(output_string);.sauter la position du vecteur lorsque pushing_back

par exemple le contenu du fichier

bob 
jack 
snack 

après avoir lu dans le vecteur,

contenu vecteur de données

bob 
jack 
snack 

après l'ajout d'une nouvelle chaîne, nouvelle chaîne étant données "john" le contenu vectoriel devient

bob 
jack 
snack 
john 

mais si je lance le programme à nouveau et utiliser la ligne de commande pour ajouter quelque chose de nouveau, il saute une position de vecteur

bob 
jack 
snack 
john 

peter 

et il le fait pour tout ce que j'ajouter après la première. Pourquoi fait-il cela?

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


if (argc > 6){ 
    cout<<"[Error] too many inputs provided" << endl; 
    return 0; 
} 

commandProcess(argc,argv); 

outputstringformat(); 
//********* 
if (cominput.rem_contpos == -1){ 
    readData();      //reads data from a file into vector data 
    int outlen = output_string.length(); 
    if (outlen > 0){ 
    data.push_back(output_string); //pushing what i had in argv to vector 
    } 

    cout<<"----------data vector------------"<<endl; 
    for (int i = 0; i < data.size();i++){ 
    cout<<"data: " << data[i] << endl; 
    } 

    ofstream outfile("contactlist.dat"); 
    number_of_contacts = data.size(); 
    if(outfile.is_open()){ 
    for (int i =0; i < number_of_contacts; i++){ 
    outfile << data[i] << endl; //copying evertthing back to file, including the new argument passed to data 
    } 
    outfile.close(); 
    } 
} 
return 0; 
} 

EDIT: aussi voici comment je traite mes arguments, je les combine en une seule chaîne. J'ai un soupçon cela pourrait être le problème mais ne le vois toujours pas ...: |

void outputstringformat(){ 

    if (cominput.name1.length() != 0){ 
     output_string = cominput.name1; 
    } 
    if (cominput.name2.length() != 0){ 
     output_string = output_string + " " + cominput.name2; 
    } 
    if (cominput.name3.length() != 0){ 
     output_string = output_string + " " + cominput.name3; 
    } 
    if (cominput.email.length() != 0){ 
     output_string = output_string + " " + cominput.email; 
    } 
    if (cominput.phone.length() != 0){ 
     output_string = output_string + " " + cominput.phone; 
    } 
} 

mis à jour avec reaData

void readData(){ 
    ifstream myfile("contactlist.dat"); 
    if(myfile.is_open()){ 
     while(!myfile.eof()){ 
      getline(myfile,line); 
      data.push_back(line); 
     } 
     myfile.close(); 
    } 
} 

Répondre

1

Ce qui pourrait se produire est que l'origine, le contenu du fichier sont la chaîne:

"bob\n" 
"jack\n" 
"snack" // no line feed 

qui, ligne par ligne, est « prise » « bob », et "casse-croûte". Lorsque vous écrivez ces lignes le long avec « john » endl, le contenu du fichier sont:

"bob\n" 
"jack\n" 
"snack\n" 
"john\n" // line feed 

Vous pouvez lire ceci comme une « bob », « jack », « casse-croûte », « John », et "" car après la lecture de "jean \ n", la fin du fichier n'a pas encore été atteinte, mais elle sera atteinte lors de la prochaine tentative de lecture.

EDIT: CereadData ne fonctionnera probablement pour vous:

void readData() { 
    ifstream myfile("contactlist.dat"); 
    if(myfile.is_open()){ 
     string l; 
     while(myfile >> l){ 
      data.push_back(l); 
     } 
     myfile.close(); 
    } 
} 

Comme il est démontré à http://codepad.org/INgm757m, cette version aura le même comportement indépendamment du fait que le dernier caractère dans contactlist.dat est un saut de ligne.

+0

je vous remercie beaucoup! – silent

0

Il n'y a pas vraiment assez pour continuer, mais je soupçonne que readData() est l'ajout d'une chaîne vide au vecteur. Essayez ceci:

// Put this right after readData() 
cout<<"----------data vector from file------------"<<endl; 
for (int i = 0; i < data.size();i++){ 
    cout<<"data[" << i << "]: " << data[i] << endl; 
} 

EDIT:
Je ne suis pas familier avec votre version de getline, mais regarder comme si ça monte la finale CR ou LF ou autre. Essayez ceci:

void readData(){ 
    ifstream myfile("contactlist.dat"); 
    if(myfile.is_open()){ 
     while(!myfile.eof()){ 
      getline(myfile,line); 
      if(myfile.gcount()>0){ // checking for zero-length string 
       data.push_back(line); 
      } 
     } 
     myfile.close(); 
    } 
} 
+0

vous avez raison ... pourriez-vous me dire ce qui est mal ici? Readflow() { \t ifstream myfile ("contactlist.dat"); \t si (myfile.is_open()) { \t \t tandis que { \t \t \t getline (monfichier, ligne) (myfile.eof()!); \t \t \t data.push_back (ligne); \t \t} \t \t myfile.close(); \t} } – silent

2

Voici votre problème:

while(!myfile.eof()){ 
    getline(myfile,line); 
    data.push_back(line); 
} 

myfile.eof() sera seulement vrai après vous avez essayé de lire au-delà de la fin du fichier; il ne vous dit pas si la prochaine lecture atteindra EOF. Donc, votre dernier getline ne lira rien (à cause de EOF), mais vous mettrez quand même la chaîne vide line dans le vecteur.

La bonne façon d'écrire cette boucle est tout simplement:

while(getline(myfile,line)) { 
    data.push_back(line); 
}  

Cela fonctionne parce que la valeur de retour de getline est le flux qui a été lu à partir (myfile, dans ce cas), et iostreams sont conçus de telle sorte que Lorsqu'elles sont utilisées dans un test, tel que if (myfile), elles sont vraies si et seulement si aucune erreur ou EOF n'a été rencontré. Écrit de cette façon, lorsque EOF est atteint, getline renverra myfile, ce qui donnera false dans le test while, ainsi la ligne ne sera pas insérée dans le vecteur.

Cette méthode a également l'avantage d'arrêter la lecture de fichier sur des erreurs autres que EOF.