GNT sans publicité, site mobile, fonctionnalitées exclusives...

débutant avec fgetc, fscanf, fprintf

Le
bpascal123
Hello cyberspace,

Je dois écrire un code qui lit un fichier et recopie le contenu
(enregistrement par enregistrement) dans un autre fichier. Je suis
arrivé à copier sur l'autre fichier sans trop de mal. Au départ, j'ai
fait appel à feof avec while ( !feof(P_SOURCE) != EOF ) fscanf fichier
sourcefprintf fichier destination . Je me suis rendu compte de
cette manière qu'à chaque fois, dans le fichier destination, il y
avait un un "ÿ" en fin fichier en dernière ligne. Je me demande si
quelqu'un n'a pas déjà rencontré l'affichage de ce caratère (ÿ) ?=
Est-
ce que c'est une représentation de EOF ?

Bref, j'ai pu résoudre cette situation avec while ( (c =
fgetc(P_SOURCE)) != EOF ) Au niveau de l'écriture du fichier tout
se déroule normalement et le résultat est ce que j'attends que ça soi=
t
enregistrement par enregistrement ou caractère par caractère

Maintenant je souhaite afficher à l'écran (dans le terminal) le
fichier destinatation et alors tout ce qui chaîne de caractère
s'affiche comme prévu mais les %d ne s'affichent pas comme prévu.
Voici les fonctions que j'utilise :


void ReadAndCopyRec( FILE *FP_SOURCE, FILE *FP_DESTI, int FTicket,
char FName[], char FPren[] )
{
while ( !feof(FP_SOURCE) )
{
fscanf(FP_SOURCE, "%d%s%s", &FTicket, FName, FPren) ;
fprintf(FP_DESTI, "%d%s%s", FTicket, FName, FPren) ;
}
}

void DisplayRec( FILE *FP_DESTI, int FTicket, char FName[], char
FPren[],
int nmax)
{
int c ;

while ( (c = fgetc(FP_DESTI)) != EOF )
{
fscanf(FP_DESTI, "%d%s%s", &FTicket, FName, FPren) ;
printf("%d%s%s", FTicket, FName, FPren) ;
}
}

Faire appel à ces 2 fonctions fonctionne bien pour ce qui est de la
copie dans le fichier destination, par contre l'affichage à l'écran
avec DisplayRec n'est pas celui de la copie ni du source pour %d,
FTicket. Le numéro de FTicket devien 0 à l'affichage écran alors qu'i=
l
est bien celui du fichier source dans le fichier destination.

Avec int FTicket[] dans les fonctions et (FTicket+i) dans fscanf et
FTicket[i] pour printf (int i = 0 et i++ dans while) pour une
lecture par adresse, le résultat est différent sans être meilleur.

Une idée?

Merci,
Pascal
Lire les 7 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
-ed-
Le #22493561
On 22 août, 03:24, ""
Hello cyberspace,

Je dois écrire un code qui lit un fichier et recopie le contenu
(enregistrement par enregistrement) dans un autre fichier. Je suis
arrivé à copier sur l'autre fichier sans trop de mal. Au départ, j' ai
fait appel à feof avec while ( !feof(P_SOURCE) != EOF ) fscanf fichie r
source...fprintf fichier destination ... . Je me suis rendu compte de
cette manière qu'à chaque fois, dans le fichier destination, il y
avait un un "ÿ" en fin fichier en dernière ligne. Je me demande si
quelqu'un n'a pas déjà rencontré l'affichage de ce caratère (ÿ) ? Est-
ce que c'est une représentation de EOF ?



La première chose à faire avant d'utiliser une fonction est de lire sa
doc et de la comprendre. Relit la doc de feof() et tu verras qu'elle
ne fait pas ce que tu crois.

Pour déterminer si on est arrivé en fin de fichier, on teste la valeur
retournée par la fonction de lecture. Il n'y a pas d'alternative.

Bref, j'ai pu résoudre cette situation avec while ( (c =
fgetc(P_SOURCE)) != EOF ) ... Au niveau de l'écriture du fichier tout
se déroule normalement et le résultat est ce que j'attends que ça s oit
enregistrement par enregistrement ou caractère par caractère...



Effectivement c'est une solution correcte. (test de la valeur
retournée par fgetc()). D'ailleurs, pour une copie simple, on peut
simplifier par :

while (fgetc(P_SOURCE) != EOF )
...

Maintenant je souhaite afficher à l'écran (dans le terminal) le
fichier destination et alors tout ce qui chaîne de caractère
s'affiche comme prévu mais les %d ne s'affichent pas comme prévu.
Voici les fonctions que j'utilise :

void ReadAndCopyRec( FILE *FP_SOURCE, FILE *FP_DESTI, int FTicket,
                                                                                 char FName[], char FPren[] )
{
        while ( !feof(FP_SOURCE) )
        {
                fscanf(FP_SOURCE, "%dn%sn%sn", &FTicke t, FName, FPren) ;
                fprintf(FP_DESTI, "%dn%sn%sn", FTicket , FName, FPren) ;
        }

}



Encore une fois feof() ne fait pas ce que tu crois. ... Il faut tester
la valeur retournée par la fonction de lecture (ici, fscanf()). Et pas
de devinettes. LIRE LA DOC. D'autre part, les 'n' dans le formatage
de fscanf() ne font pas non plus ce que tu crois. Ça perturbe tout...
A retirer. Il ne faut pas programmer au hasard, mais se conformer
strictement à la doc...
kikonc
Le #22496171
:
Hello cyberspace,


void ReadAndCopyRec( FILE *FP_SOURCE, FILE *FP_DESTI, int FTicket,
char FName[], char FPren[] )
{
while ( !feof(FP_SOURCE) )



...


void DisplayRec( FILE *FP_DESTI, int FTicket, char FName[], char
FPren[],
int nmax)
{
int c ;

while ( (c = fgetc(FP_DESTI)) != EOF )


...

Mais c'est une blague ! Remplacer feof par fgetc ... après c'est normal que
cela ne puisse fonctionner de la même façon, en tant que comptable cela
devrait te sauter aux yeux !


Avec int FTicket[] dans les fonctions et (FTicket+i) dans fscanf et
FTicket[i] pour printf (...int i = 0 et i++ dans while) pour une
lecture par adresse, le résultat est différent sans être meilleur.



Avant d'arriver à l'arithmétique des pointeurs, il faudrait déjà comme le
dit "ed" réussir à comprendre la doc sur les fonctions les plus simples.
bpascal123
Le #22501691
EOF...

J'ai lu la doc, en tant que comptable, il semble que feof ait un
passif non négligeable... :) Je dis en tant que comptable car certains
pensent que la comptablité se fait avec un cahier, une règle de
préférence longue pour tracer des traits, un bic et une calculatrice
ou une bonne tête pour le calcul de tête ... je pense que ce n'est pas
le sujet de cette discussion

Bref, d'après la doc ou plutôt des recherches, feof peut afficher 2
fois le dernier enregistrement lu, la 2ème fois est dû au premier
appel de la fonction à l'intérieur de la boucle test qui renvoie faux
et crée un "doublon" par un second affichage du dernier enregistrement
qui ne devrait pas avoir lieu...

Voilà ce que j'ai fait et c'est très bizarre mais j'ai cru un moment
que cette solution me suffisait pour mon niveau mais en fait c'est
encore moins fonctionnel :

void ReadAndCopyRec(FILE *FP_SOURCE, FILE *FP_DESTI, int FTicket, char
FName[], char FPren[])
{
while (1)
{
fscanf(FP_SOURCE, "%d%s%s", &FTicket, FName, FPren) ;
if ( feof(FP_SOURCE) )
break ;
fprintf(FP_DESTI, "%dn%sn%sn", FTicket, FName, FPren) ;
}
}

void DisplayRec(FILE *FP_DESTI, int FTicket, char FName[], char
FPren[] )
{
int i = 0 ;
while (1)
{
fscanf(FP_DESTI, "%d%s%s", &FTicket, FName, FPren) ;
if ( feof(FP_DESTI) )
break ;
printf("nTicket no. %d ", FTicket) ;
printf("nNom du titulaire : %s", FName ) ;
printf("nPrenom du titulaire : %s", FPren) ;
i++ ;
}
}

j'ai enlevé les n de la lecture de fscanf, c'est sûre qu'avec la
méthode de saisie plus haut, ça fonctionne. Mais ici avec feof à cett e
position, c'est juste un désordre, soit une boucle infinie, soit une
répétition de 100x puis stop à un chiffre nombre entré dans le corp s
du programme main...

A qui peut aider,
merci
Antoine Leca
Le #22502211
écrivit :
A qui peut aider,



On va voir si on peut essayer¹.

fscanf(FP_DESTI, "%d%s%s", &FTicket, FName, FPren) ;



En C, fscanf est une fonction qui retourne un résultat. Ce résultat, tu
ne PEUX PAS faire comme s'il n'existe pas (comme tu pourrais le faire
avec printf): if FAUT vérifier que la fonction a bien fonctionné comme
prévu, et en l'occurrence elle devrait renvoyer 3 (le nombre d'objet
lus), ou encore EOF (si tu es à la fin de fichier au début de la lecture
: avantage, cela économise un appel à feof() ensuite !) ;
une autre valeur doit être prise en compte et annuler le reste du
traitement, cela indique une erreur dans les données.

Une manière de faire est d'écrire :

#include
/* ... */

{
int r;

r = fscanf(FP_DESTI, "%d%s%s", &FTicket, FName, FPren);
if( r == EOF )
break;
assert(r == 3);


Nota : ce n'est pas du code industriel, mais cela suffit amplement pour
ce que tu fais ; on peut aussi écrire
if( r != 3 ) routine_d_erreur("machin", "truc");
mais assert() revient au même au point où tu es (et il n'est point
besoin d'écrire routine_d_erreur ;-) ).


Autre point sans relation, il manque
putchar('n');
à la fin de DisplayRec.


Antoine
_____
¹: on notera que je prend des précautions.
-ed-
Le #22502201
On 25 août, 02:16, ""
EOF...

J'ai lu la doc, en tant que comptable, il semble que feof ait un



Bah on dirait pas. Tu n'as toujours compris que feof() ne servait pas
à déterminer la fin de lecture. A quoi ça sert qu'on te fournisse des
réponses si tu ne les lit pas ? J'ai indiqué comment on détermine la
fin de lecture. Fait le. Point.

Une fois la fin de lecture détectée (rappel : en testant la valeur
retournée par la fonction de lecture); on peut (mais c'est rarement
utile) déterminer la CAUSE de la fin de lecture en appelant feof() et
ferror(). Mais tout ça, c'est déjà la doc que tu devrais avoir lu. ne
pas se laisser intoxiquer par le nom des fonctions. Le C est un
langage industriel et non universitaire. Il n'a pas pour vocation
d'enseigner la programmation (donc pas du tout un langage de
débutant), mais de faire exactement ce pour quoi il a été conçu. LI RE
LA DOC DE TOUTES LES FONCTIONS AVANT DE LES UTILISER.

Une référence très sûre : http://www.opengroup.org/onlinepubs/79909 89775/

C'est en anglais, bien sûr ...

Et si tu ne comprends pas la doc, demande des explications.
Publicité
Suivre les réponses
Poster une réponse
Anonyme