Oui... C'est bien ce qu'il me semblait, il y a de la place pour le progrès
(soit dis sans offance
)
Tu mélanges allègrement du C avec du C++, et, à moins de savoir exactement ce que tu fais, c'est en général une bien mauvaise idée.
Pour commencer, je voudrais attirer ton attention sur le fait que les flux C++ disposent d'un opérateur de conversion implicite en booléen qui vaut true si la prochaine tentative de lecture est sensée réussir, et donc, entre autres choses, si la fin du fichier n'a pas été atteinte.
Comme la fin de lecture est loin d'être la seule raison pour laquelle la lecture suivante risque d'échouer, il est fortement préférable de profiter de cet opérateur de conversion 
Il se fait que la fontion getline renvoie... le flux à partir duquel elle a travailler.
Tu peux donc, afin de te faciliter la vie, effectuer une boucle de type "tant que" dont la condition pour y retrourner est que le flux soit valide, sous la forme de
while(std::getline(InputFileSpotsAndVariance,str))
(Au fait, si j'avais été toi, j'aurais sans doute choisi un nom encore plus long pour le flux à utiliser, même si celui-ci est particulièrement parlant sur ce que tu lis 
)
Ensuite, comme je te l'ai fait remarquer plus haut, l'utilisation des fonctions issues de C sont rarement la meilleure manière de travailler en C++, ne serait-ce que par leur manque récurrent de sécurité à l'utilisation.
Or, il se fait que C++ propose une classe géniale pour transformer une chaine de caractères en "n'importe quoi d'autre" et réciproquement: la classe stringstream.
(Nota: je pourrais aussi te parler de boost.tokenizer qui serait sans doute idéal pour tes besoins, mais je vais me contenter de donner une solution "a mano"
)
Cette classe permet de récupérer n'importe quoi (et surtout des types primitif) au départ d'une chaine de caractères en utilisant exactement la même syntaxe que pour les autres flux (les opérateurs << pour introduire une donnée dans le flux et >> pour récupérer une donnée à partir du flux), et comble de bonheur, elle est compatible avec la fonction libre getline, dont tu l'ignore peut-être, mais elle supporte un troisième paramètre qui représente le caractère de séparation 
Tu pourrais donc envisager de vérifier par la même occasion que ton fichier est "correctement formé"
tu pourrais donc te "contenter" d'un code proche de
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| std::string str; // la chaine utilisée pour la lecture de la chaine
while(std::getline(InputFileSpotsAndVariance,str)) // j'ai repris ton nom :D
{
/* création d'un flux de conversion */
std::stringstream ss;
/* on place la chaine lue dans le flux de conversion */
ss<<str;
/* il nous faut :
* - une chaine de caractères
* - un entier (pour représenter scenario)
* - deux réels (pour représenter respectivement St et Vt)
*/
std::string temp;
int scenario;
double st;
double vt;
std::getline(ss,temp,'='); // récupération de la première parite
if(temp!=";scenario") // la première donnée doit avoir trait au scenario
throw badFileFormat(); // à toi de créer cette classe d'exception ;)
if(!ss>>scenario) // on lit la première donnée
// si la lecture échoue, le format du fichier n'est pas bon
throw badFileFormat();
std::getline(ss,temp,'='); //récupération de la deuxième partie
if(temp!=";St") // la deuxième donnée doit avoir trait à St
throw badFileFormat();
if(!ss>>st) // on lit la deuxième donnée
// si la lecture échoue, le format du fichier n'est pas bon
std::getline(ss,temp,'='); // récupération de la troisième partie
if(temp!=";Vt") // la deuxième donnée doit avoir trait à Vt
throw badFileFormat();
if(!ss>>vt) // on lit la deuxième donnée
// si la lecture échoue, le format du fichier n'est pas bon
/* le traitement que tu veux: je me contente ici de réafficher les
* données récupérées :D
*/
std::cout<<"scenario "<<scenario<<" valeur de St "<<st
<<"valeur de Vt "<<vt;
} |
Partager