Votre question

[C] De la fonction fscanf...

Tags :
  • Programme
  • Programmation
Dernière réponse : dans Programmation
22 Mars 2012 12:49:49

Bonjour,

J'avais une question quant à une particularité de la fonction fscanf en C.
Supposons que j'ai un fichier texte pointé par un pointeur FILE *pFile contenant plusieurs lignes, et des colonnes contenant des nombres (double) séparés par des tab (\t), et que je veuille récupérer 10 nombres dans un tableau double. Je positionne mon curseur au bon endroit dans mon fichier, puis je tape :
  1. // Début de ma fonction
  2. double tableau [10];
  3. // [...] etc...
  4. fscanf(pFile, "%le\t%le\t%le\t%le\t%le\t%le\t%le\t%le\t%le\t%le", tableau);

alors j'ai une erreur à l'exécution du programme. Du coup je suis obligé de faire :
  1. // Début de ma fonction
  2. double tableau [10];
  3. // [...] etc...
  4. fscanf(pFile, "%le\t%le\t%le\t%le\t%le\t%le\t%le\t%le\t%le\t%le",
  5. tableau, tableau+1, {etc ....}, tableau + 9);

...ce qui est assez pénible à écrire (surtout que moi j'en ai 40 des nombres !!!)
Petite précision (je ne pense pas que ce soit important mais bon...) : mon tableau est en fait crée par un malloc et détruit comme il se doit.

Je voulais savoir s'il existait une façon condensée de stocker le contenu de plusieurs nombres dans un tableau sans devoir énumérer chaque élément (et sans passer par une boucle for, car ça revient à faire du cas par cas).

Je me souviens que je pouvais écrire simplement
  1. // Début de ma fonction
  2. double tableau [10];
  3. // [...] etc...
  4. fscanf(pFile, "%le,%le,%le,%le,%le,%le,%le,%le,%le,%le", tableau);

lorsque mes nombres étaient séparés par des virgules... (par exemple avec scanf je sais que ça fonctionne si l'utilisateur entre les données sur le clavier en mettant des virgules).

Bref, à quoi est-ce dû ?

Merci !

Autres pages sur : fonction fscanf

a c 232 L Programmation
22 Mars 2012 15:48:03

Salut,

Je vois ce que tu essaies de faire, mais je suis pas sûr que ça puisse se faire...
Une autre solution serait de faire une boucle pour mettre chaque élément séparé par un \t et tu les insères dans le tableau.
a b L Programmation
22 Mars 2012 23:10:00

ça ne me semble pas non plus possible.

C'est là qu'on voit l'utilité du C++ avec la sérialisation/désérialisation, mais surtout le traitement des chaines de caractères. :) 

Pour faire bien, comme l'indique OmaR, tu devrais faire une fonction, et utiliser strtok (tokens) pour découper la chaine toi-même, puis convertir en double avec atof.
  1. void Deserialise( double * pDestination, char * pLigne, int tailleMax )
  2. {
  3. char * pElement;
  4. int position = 0;
  5.  
  6. pElement = strtok( pLigne, "\t" );
  7. while( pElement && position < tailleMax )
  8. {
  9. pDestination[ position ] = atof( pElement );
  10.  
  11. ++position;
  12. pElement = strtok( NULL, "\t");
  13. }
  14. }
(code non testé)

Après, tu utilises fgets au lieu de fscanf et tu appelles la fonction:
  1. double tableau [10];
  2. char ligne[LG_CHAR_MAX];
  3. if( fgets(ligne, LG_CHAR_MAX, pFile ) )
  4. Deserialise( tableau, ligne, 10 );

23 Mars 2012 13:35:09

Merci à vous !

Comme quoi c'est vraiment à double tranchant les scanf, fscanf etc... au début on trouve cela super pratique (utilisation des %le) ... mais vus ts les pbs de tampon à vider, pb pour sérialiser, les histoires de "buffer overflow", ça compense le temps gagné par les "conversions automatiques" (je ne sais pas si c'est le bon terme).

Bon week end !
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS