2017-07-06 2 views
0

J'ai des problèmes pour afficher la sortie. Il y a toujours et une ligne supplémentaire est imprimée. J'ai fait quelques recherches et il s'avère que c'est parce que mon getline. De plus, je présente mes excuses pour le formatBesoin d'aide pour utiliser getline dans un fichier

#include <iostream> 
#include <fstream> 
#include <string> 

using namespace std; 

struct menuItemType 
{ 
string menuItem; 
double menuPrice; 
}; 

int main() 
{ 
menuItemType plainEgg; 
menuItemType baconEgg; 
menuItemType muffin; 
menuItemType frenchToast; 
menuItemType fruitBasket; 
menuItemType cereal; 
menuItemType coffee; 
menuItemType tea; 

ifstream infile; 
infile.open("Ch9_Ex5Data.txt"); 

while(infile) 
{ 
getline(infile,plainEgg.menuItem); 
infile >> plainEgg.menuPrice; 

getline(infile,baconEgg.menuItem); 
infile >> baconEgg.menuPrice; 

getline(infile,muffin.menuItem); 
infile >> muffin.menuPrice; 

getline(infile,frenchToast.menuItem); 
infile >> frenchToast.menuPrice; 

getline(infile,fruitBasket.menuItem); 
infile >> fruitBasket.menuPrice; 

getline(infile,cereal.menuItem); 
infile >> cereal.menuPrice; 

getline(infile,coffee.menuItem); 
infile >> coffee.menuPrice; 

getline(infile,tea.menuItem); 
infile >> tea.menuPrice; 

cout << plainEgg.menuItem << plainEgg.menuPrice << endl; 
cout << baconEgg.menuItem << baconEgg.menuPrice << endl; 
cout << muffin.menuItem << muffin.menuPrice << endl; 
cout << frenchToast.menuItem << frenchToast.menuPrice << endl; 
cout << fruitBasket.menuItem << fruitBasket.menuPrice << endl; 
cout << cereal.menuItem << cereal.menuPrice << endl; 
cout << coffee.menuItem << coffee.menuPrice << endl; 
cout << tea.menuItem << tea.menuPrice << endl; 
} 
infile.close(); 

return 0; 
} 

Contenu dans le fichier

Plain Eggs 
1.45 
Bacon and Eggs 
2.45 
etc. 

J'ai essayé d'utiliser

if (infile.eof()) 
    cout << endl; 

c'est ma sortie

Plain Egg1.45 // <-- this is the only correct output 
Bacon 
and Egg2.45 
Muffin 
0.99 
French 
Toast1.99 
Fruit 
Basket2.49 
Cereal 
0.69 
Coffee 
0.50 
Tea 
0.75 

chose seulement qui a imprimé correctement était le premier ligne. (Note) Je dois utiliser la structure.

+0

Tester les erreurs lors de la lecture, pas une fois avant d'avoir lu 16 fois si toutes ces erreurs pouvaient échouer. Vous allez aussi avoir du mal à mélanger getline et '>>' sans que certains ignorent pour manger les nouvelles lignes restantes. Puisque votre prix est une chaîne, vous pourriez aussi bien lire toute la ligne et vous simplifier la vie. Vous pourriez aussi penser à un tableau. –

+0

Vous ne pouvez pas utiliser eof() après getline parce que c'est la fin du fichier. Vous devriez probablement vérifier EOL ou utiliser un \ n comme un délimiteur dans getline() et utiliser get line() au lieu de >> –

+0

Ceci est une bonne lecture sur le mélange 'getline' et' >> '. https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction –

Répondre

0

Il existe au moins trois problèmes majeurs dans le code indiqué. Le premier ne vérifie pas correctement une condition de fin de fichier:

while(infile) 

Ceci vérifie si le flux d'entrée déjà est entré dans un état échoué. Après la lecture de la dernière ligne de votre fichier, votre flux d'entrée n'a pas encore échoué.

Tout, jusqu'au point, est allé exactement comme prévu. Donc, après la dernière ligne du fichier, cette condition sera toujours vraie, en exécutant la boucle une fois de plus. Bien sûr, il échouera misérablement.

Et vérifier explicitement if (infile.eof()) volonté, encore une fois, si le fichier a déjà une fin rencontré de fichier condition.

Qu'est-ce que vous voulez sans doute faire est de essayer pour commencer à lire la ligne suivante à partir du fichier, et si elle échoue, vous avez atteint la fin de celui-ci:

while (getline(infile,plainEgg.menuItem)) 
{ 
     // The code that reads the next set of items. 

Mais, seul, ne résoudra pas tous vos problèmes.

getline(infile,plainEgg.menuItem); 
infile >> plainEgg.menuPrice; 

Ceci est le mélange d'une opération d'entrée non mis en forme, std::getline(), avec une opération d'entrée en forme, l'opérateur >>.

Une telle combinaison est fragile, et a plusieurs modes de défaillance non évidents, as explained here, donc je ne le répéterai pas; il suffit de voir cette question plus tôt pour plus d'informations.

Bien qu'il existe des façons de le faire correctement, il va être plus facile pour vous de réécrire votre code pour utiliser uniquement std::getline() ou l'opérateur >> pour lire tout, jusqu'à ce que vous comprenez comment combiner correctement les opérations d'entrée non formatées et formatées .

Le dernier problème est un petit problème. Le code affiché ne gère pas correctement les entrées incomplètes et la vérification des erreurs. Comme indiqué, tant qu'il lit avec succès la première partie d'un ensemble de données, il suppose que les données restantes seront là.Vous devez vérifier que chaque opération d'entrée (que vous choisissiez d'utiliser des opérations d'entrée formatées ou non formatées) soit correctement vérifiée pour la réussite.