Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

separateurs avec fscanf ?

7 réponses
Avatar
Bernard Adrian
Bonjour,

Y a t'il un moyen de faire passer le caractère ";" à fscanf comme
séparateur de champs ?

Je cherche à récupérer des données contenues dans des champs séparés par
ces ";" dans un fichier texte.

fscanf(INFILE,"%s;%s;%s;%s\n", ch1,ch2,ch3,ch4) ne fonctionne pas.

Par contre fscanf(INFILE,"%s\t%s\t%s\t%s\n", ch2,ch2,ch3,ch4) fonctionne à
condition d'avoir remplacé les points-virgules par des tabulations dans le
fichier lu.

Merci,
--
Bernard Adrian http://bernadrian.free.fr

7 réponses

Avatar
Anthony
Bernard Adrian wrote:

Bonjour,


Bonjour,


Y a t'il un moyen de faire passer le caractère ";" à fscanf comme
séparateur de champs ?

Je cherche à récupérer des données contenues dans des champs séparés par
ces ";" dans un fichier texte.

fscanf(INFILE,"%s;%s;%s;%sn", ch1,ch2,ch3,ch4) ne fonctionne pas.


A ma connaissance non, scanf s'arrête à tout caractère blanc dans le texte,
mais il y a une fonction toute faite pour ceci : strtok();

Ce qui donnerait (par exemple) :

#include <string.h>
[...]
char chaine[TAILLEQUIVABIEN], *t;
[...]
fgets(chaine, sizeof chaine, INFILE);

if((t = strtok(chaine, ";")) == NULL) {
printf("parse error!n");
}
else {
strcpy(ch1, t);
}

if((t = strtok(NULL, ";")) == NULL) {
printf("parse error!n");
}
else {
strcpy(ch2, t);
}

et ainsi de suite. Tous les appels suivant le premier doivent avoir pour
premier paramètre NULL pour indiquer que l'on parse toujours la même
chaine. En utilisant un tableau pour ch, il est simple de mettre ca dans
une boucle pour éviter la lourdeur de l'écriture. On peut aussi ne pas
vérifier le retour de strtok si on est sûr de soit, mais certains ont
essayé, ils ont eu des problèmes...


Par contre fscanf(INFILE,"%st%st%st%sn", ch2,ch2,ch3,ch4) fonctionne à
condition d'avoir remplacé les points-virgules par des tabulations dans le
fichier lu.



En fait ceci fonctionne car *scanf s'arrête au premier caractère `blanc'
soit un espace, un retour à la ligne ou une tabulation.

Anthony
--
I know my dreams are made of you, Of you and only for you
Your ocean pulls me under, Your voice tears me asunder
Love me before the last petal falls
-- Nightwish - The beauty and the beast

Avatar
gl
Bernard Adrian wrote:

Bonjour,


Bonjour,


Y a t'il un moyen de faire passer le caractère ";" à fscanf comme
séparateur de champs ?

Je cherche à récupérer des données contenues dans des champs séparés par
ces ";" dans un fichier texte.

fscanf(INFILE,"%s;%s;%s;%sn", ch1,ch2,ch3,ch4) ne fonctionne pas.



Avez vous essayez fscanf(INFILE,"%[^;];%[^;];%[^;];%sn", ch1,ch2,ch3,ch4) ?

Avatar
Horst Kraemer
Bernard Adrian wrote:

Bonjour,

Y a t'il un moyen de faire passer le caractère ";" à fscanf comme
séparateur de champs ?

Je cherche à récupérer des données contenues dans des champs séparés par
ces ";" dans un fichier texte.

fscanf(INFILE,"%s;%s;%s;%sn", ch1,ch2,ch3,ch4) ne fonctionne pas.


Le n a la fin est *très* dangereux et a des effets désastreux si
INFILE recoit les donées par le clavier. Il faut absolument le laisser
tomber. Il n'a *jamais* un sens si on ne lit pas par %c ou %[.

"n" dans *scanf a le même effet que " " ou "n t" ou " " etc.
c.a.d. toute séquence de <ESPACE> et n et t a le même effet de
sauter tous les <ESPACE> et n t qui suivent dans le flux. Mais quand
la prochaine lecture par *scanf utilise %s ou %d ou %f etc cette
séquence est sautée automatiquement parce que fscanf saute toute
séquence *initiale* de <ESOACE> et n.

Résumé: scanf("%s") extrait des *mots* séparés par des séquences de
<ESPACE> n ou t de longueur quelconque et les séquences de
séparation sont toujours sautées automatiquement lors de la lecture du
mot qui suit.

Ton problème est probablement que pour la ligne

A;B;C;D

le premier "%s" lit déja tout "A;B;C;D" parce que scanf ne s'arrète
que si elle voit un <ESPACE> n ou t ou EOF.


Une solution de ton problème serait

fscanf(INFILE,"%[^;];%[^;];%[^;];%[^n]%*c", ch1,ch2,ch3,ch4)

mais l'inconvénient est que cela ne fonctionne pas s'il y a des champs
vides comme dans

A;;;D

L'autre inconvénient de scanf en général peut échouer sans te dire
pourquoi. Donc il faut absolument vérifier la valeur renvoyée par
*scanf

ret = fscanf...

Si dans ton cas ret!=4 (le nombre des élements convertis) il y a un
problème.

Mais comme un autre lecteur à déjà dit, fgets suivi de strtok est une
méthode beaucoup plus sûre.


Par contre fscanf(INFILE,"%st%st%st%sn", ch2,ch2,ch3,ch4) fonctionne à
condition d'avoir remplacé les points-virgules par des tabulations dans le
fichier lu.


Dans ce cas un simple

fscanf(INFILE,"%s%s%s%s", ch2,ch2,ch3,ch4);

aurait le même effet selon ce que je viens d'expliquer.et les champs
pourraient être séprés par des espaces, des t ou même par des n.



--
Horst

Avatar
Dominique Baldo
Anthony nous disait
Je cherche à récupérer des données contenues dans des champs séparés par
ces ";" dans un fichier texte.

fscanf(INFILE,"%s;%s;%s;%sn", ch1,ch2,ch3,ch4) ne fonctionne pas.


A ma connaissance non, scanf s'arrête à tout caractère blanc dans le texte,
mais il y a une fonction toute faite pour ceci : strtok();


strtok ne fonctionne pas avec les champs nuls (par ex: "1;;2;3" ne
donnera que 3 champs et pas 4)

sur certaines archi il y a une fonction non standard strsep() qui résout
ce problème.

sans compter que strtok n'est pas réentrant ce qui peut poser problème.


Avatar
Bernard Adrian
Horst Kraemer écrivait
news::

Mais comme un autre lecteur à déjà dit, fgets suivi de strtok est une
méthode beaucoup plus sûre.




Merci à tous : ça roule avec strtok.

--
Bernard Adrian http://bernadrian.free.fr

Avatar
Anthony
Dominique Baldo wrote:

Anthony nous disait
A ma connaissance non, scanf s'arrête à tout caractère blanc dans le
texte, mais il y a une fonction toute faite pour ceci : strtok();


strtok ne fonctionne pas avec les champs nuls (par ex: "1;;2;3" ne
donnera que 3 champs et pas 4)


Ah très juste je ne me souvenais plus, je croyais au contraire que strtok
était la solution pour les champs nuls et resolvait le problème du scanf
avec [^;]. merci pour ce rappel. Mais donc il n'y a aucun moyen (dans la
librairie standard) de parser une chaine en autorisant des champs nuls ?
[ mis à part vérifier avant chaque appel de strtok que le prochain
caractère dans la chaine n'est pas le délimiteur ]

sans compter que strtok n'est pas réentrant ce qui peut poser problème.


dans ce cas il y a strtok_r()

Anthony
--
It's a bird.. It's a plane..
No, it's KernelMan, faster than a speeding bullet, to your rescue.
Doing new kernel versions in under 5 seconds flat..
-- Linus, in the announcement for 1.3.27


Avatar
sp00k
Franchement sa ce code une function comme sa !!!!!!!


sp00k.



"Bernard Adrian" a écrit dans le message de news:

Horst Kraemer écrivait
news::

Mais comme un autre lecteur à déjà dit, fgets suivi de strtok est une
méthode beaucoup plus sûre.




Merci à tous : ça roule avec strtok.

--
Bernard Adrian http://bernadrian.free.fr