Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2726 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] Problème fscanf avec string

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Problème fscanf avec string

n°2095110
showbas
Posté le 13-08-2011 à 23:34:55  profilanswer
 

Bonjour a tous,
 
voila ça fait deux jours que je galère sur un bout de programme (je viens de commencer a apprendre le C).
J'ai un fichier mot.txt ou il est écrit dedans : salut
Le problème c'est quand je lance mon programme, il crash  :??:  
 

Code :
  1. #include <stdio.h>
  2.     int main() {
  3.         char mot = {0};
  4.         FILE *f = fopen("mot.txt", "r" );
  5.         fscanf(f, "%s", &mot);
  6.         printf ("%s\n", mot);
  7.         fclose(f);
  8.         return 0;
  9.     }


Chose bizarre si je remplace %s par %c j'ai simplement "s" qui s'affiche (le début de "salut" je suppose).
 
Si quelqu'un a une idée de comment résoudre ce problème je suis preneur.
 
Merci beaucoup d'avance.  :jap:

Message cité 1 fois
Message édité par showbas le 13-08-2011 à 23:36:04
mood
Publicité
Posté le 13-08-2011 à 23:34:55  profilanswer
 

n°2095112
Anonymouse
Posté le 14-08-2011 à 00:04:14  profilanswer
 

Code :
  1. #include <stdio.h>
  2.     int main() {
  3.         char mot [6] = {0};
  4.         FILE *f = fopen("mot.txt", "r" );
  5.         fscanf(f, "%s", mot);
  6.         printf ("%s\n", mot);
  7.         fclose(f);
  8.         return 0;
  9.     }

Message cité 1 fois
Message édité par Anonymouse le 14-08-2011 à 00:30:28
n°2095113
showbas
Posté le 14-08-2011 à 00:09:42  profilanswer
 

Anonymouse a écrit :

Code :
  1. #include <stdio.h>
  2.     int main() {
  3.         char mot [6] = {0};
  4.         FILE *f = fopen("mot.txt", "r" );
  5.         fscanf(f, "%s", &mot);
  6.         printf ("%s\n", mot);
  7.         fclose(f);
  8.         return 0;
  9.     }



Merci de me répondre. Par contre ça ne marche toujours pas...

n°2095115
Anonymouse
Posté le 14-08-2011 à 00:31:20  profilanswer
 

showbas a écrit :


Merci de me répondre. Par contre ça ne marche toujours pas...


 
On compile avec les warnings et on enlève le & en trop devant mot.

Message cité 1 fois
Message édité par Anonymouse le 14-08-2011 à 00:31:53
n°2095117
showbas
Posté le 14-08-2011 à 01:30:25  profilanswer
 

Anonymouse a écrit :


 
On compile avec les warnings et on enlève le & en trop devant mot.


ben j'ai même pas de warning vu que c'est explorer qui me dit que ça plante :
 
http://img8.imageshack.us/img8/6167/capturekco.png
 
Et pour le & je crois bien qu'il faut le laisser vu qu'on indique l'adresse de mot, son contenu n’intéresse pas fscanf.

n°2095126
Trap D
Posté le 14-08-2011 à 09:53:52  profilanswer
 

showbas a écrit :

Bonjour a tous,

 

voila ça fait deux jours que je galère sur un bout de programme (je viens de commencer a apprendre le C).
J'ai un fichier mot.txt ou il est écrit dedans : salut
Le problème c'est quand je lance mon programme, il crash  :??:

 
Code :
  1. #include <stdio.h>
  2.     int main() {
  3.         char mot = {0};
  4.         FILE *f = fopen("mot.txt", "r" );
  5.         fscanf(f, "%s", &mot);
  6.         printf ("%s\n", mot);
  7.         fclose(f);
  8.         return 0;
  9.     }


Chose bizarre si je remplace %s par %c j'ai simplement "s" qui s'affiche (le début de "salut" je suppose).

 

Si quelqu'un a une idée de comment résoudre ce problème je suis preneur.

 

Merci beaucoup d'avance.  :jap:

Il faudrait tester le retour de fopen, c'est le minimum.

Code :
  1. #include <stdio.h>
  2.     int main(void) {
  3.         char mot[1024] = {0};
  4.         FILE *f = fopen("mot.txt", "r" );
  5.        if (f == NULL)
  6.        {
  7.            puts("Pb ouverture fichier" );
  8.        }
  9.        else
  10.       {
  11.            fscanf(f, "%s", &mot);
  12.            printf ("%s\n", mot);
  13.            fclose(f);
  14.       }
  15.       return 0;
  16.     }


Cela ne règle pas tous les problèmes (en particulier la longueur du mot que tu vas lire, c'est  pourquoi j'ai mis 1024) mais c'est déjà mieux.
D'autre part, tu veux lire un mot, donc une suite de caractères, tu vas donc donner à fscanf une adresse où ranger les caractères. En C un tableau est en fait une adresse mémoire et le compilo s'arrange pour que tu puisses ranger tous les caractères qui sont prévus pour ce tableau, dans mon cas 1024. mot étant un tableau il n'y a pas besoin de mettre le &.
Dons ton premier code, tu as écris char mot donc tu dis que mot est un caractère, il faut donc alors effectivement mettre un & devant mot pour le fscanf qui prendra cette adresse, mais ici, mot n'est pas un tableau, alors fscanf va écrire consciensieusement les caractères lus (tu lui as dis de lire une suite de caractères : fscanf avec %s) donc il va écraser la mémoire est tu auras un crash.

 
Citation :

Chose bizarre si je remplace %s par %c j'ai simplement "s" qui s'affiche (le début de "salut" je suppose).

Pas du tout bizarre mais tout à fait normal, tu as par contre de la chance !
Si tu mets fscanf avec %c, tu indiques que tu veux lire un caractères, tu indiques l'adresse où le ranger avec &mot, fscanf fait ce qu'on lui dit de faire tout va bien.
Où tu as de la chance c'est le printf("%s \n", mot) si c'est ce que tu as écris (je penche plutôt pour printf("%s \n", &mot) car tu dis que tu veux écrire une chaine de caractère débutant à l'adresse de mot, or en C une chaine doit se terminer par \0 donc comme l'écriture se passe bien, à l'adresse de mot + 1 il y avait un \0 : une chance sur 256 !
Par contre, si tu as écrit printf("%c \n", mot) alors c'est tout ce qu'il y a de normal, tu dis que tu veux écrire la valeur du caractère mot sous forme de caractère et non de nombre.

Message cité 1 fois
Message édité par Trap D le 14-08-2011 à 10:06:57
n°2095128
showbas
Posté le 14-08-2011 à 11:12:42  profilanswer
 

Trap D a écrit :

Il faudrait tester le retour de fopen, c'est le minimum.

Code :
  1. #include <stdio.h>
  2.     int main(void) {
  3.         char mot[1024] = {0};
  4.         FILE *f = fopen("mot.txt", "r" );
  5.        if (f == NULL)
  6.        {
  7.            puts("Pb ouverture fichier" );
  8.        }
  9.        else
  10.       {
  11.            fscanf(f, "%s", &mot);
  12.            printf ("%s\n", mot);
  13.            fclose(f);
  14.       }
  15.       return 0;
  16.     }


Cela ne règle pas tous les problèmes (en particulier la longueur du mot que tu vas lire, c'est  pourquoi j'ai mis 1024) mais c'est déjà mieux.
D'autre part, tu veux lire un mot, donc une suite de caractères, tu vas donc donner à fscanf une adresse où ranger les caractères. En C un tableau est en fait une adresse mémoire et le compilo s'arrange pour que tu puisses ranger tous les caractères qui sont prévus pour ce tableau, dans mon cas 1024. mot étant un tableau il n'y a pas besoin de mettre le &.
Dons ton premier code, tu as écris char mot donc tu dis que mot est un caractère, il faut donc alors effectivement mettre un & devant mot pour le fscanf qui prendra cette adresse, mais ici, mot n'est pas un tableau, alors fscanf va écrire consciensieusement les caractères lus (tu lui as dis de lire une suite de caractères : fscanf avec %s) donc il va écraser la mémoire est tu auras un crash.  
 

Citation :

Chose bizarre si je remplace %s par %c j'ai simplement "s" qui s'affiche (le début de "salut" je suppose).

Pas du tout bizarre mais tout à fait normal, tu as par contre de la chance !
Si tu mets fscanf avec %c, tu indiques que tu veux lire un caractères, tu indiques l'adresse où le ranger avec &mot, fscanf fait ce qu'on lui dit de faire tout va bien.  
Où tu as de la chance c'est le printf("%s \n", mot) si c'est ce que tu as écris (je penche plutôt pour printf("%s \n", &mot) car tu dis que tu veux écrire une chaine de caractère débutant à l'adresse de mot, or en C une chaine doit se terminer par \0 donc comme l'écriture se passe bien, à l'adresse de mot + 1 il y avait un \0 : une chance sur 256 !
Par contre, si tu as écrit printf("%c \n", mot) alors c'est tout ce qu'il y a de normal, tu dis que tu veux écrire la valeur du caractère mot sous forme de caractère et non de nombre.


Merci beaucoup pour toutes ces précisions effectivement ça marche très bien avec ton code le fait d'avoir indiqué 1024 a mot a réglé le problème.  
Je comprend également mieux le fonctionnement de fprintf.
Merci beaucoup.  :)

n°2095133
showbas
Posté le 14-08-2011 à 11:34:22  profilanswer
 

Désolé je reviens avec un autre problème... je réalise un pendu en C le problème est que la si j'applique la méthode Trap D m'a expliquée ça ne fonctionne pas (j'ai encore un crash).
Voila le code, ne vous préoccupez pas trop de toutes les variables c'est surtout les opérations sur les fichier qui sont importantes. Le fichier qui m’intéresse est fichier2. Avant de faire le fscanf je fais déjà d'autres opérations sur fichier2 ça explique peut-être pourquoi il crash. Peut-être faut-il se repositionner au début du fichier ?? J'avoue être un peu perdu.

Code :
  1. int testlettre(char *copylettre, int *copyok)
  2. {
  3.     int reussite=0;
  4.     int i=0;   
  5.     char motsauv[1024] = {0};
  6.     int caractereActuel = 0;
  7.     int caractereSauv = 0;
  8.     FILE* fichier = NULL;
  9.     FILE* fichier2 = NULL;
  10.     fichier = fopen("test.txt", "r" );
  11.     fichier2 = fopen("sauv.txt", "r" );
  12.     if (fichier != NULL && fichier2 != NULL)
  13.     {
  14.         caractereActuel = fgetc(fichier);
  15.         caractereSauv = fgetc(fichier2);
  16.         while (caractereActuel != EOF)
  17.         {
  18.             if (caractereActuel == *copylettre && caractereSauv != *copylettre)
  19.             {
  20.                 fprintf(fichier2,copylettre);
  21.                 reussite++;
  22.             }
  23.             else
  24.             {
  25.                 fprintf(fichier2,"_" );
  26.             }
  27.             caractereActuel = fgetc(fichier);
  28.             caractereSauv = fgetc(fichier2);
  29.             i++;
  30.         }
  31.         printf("debug1" );
  32.         fscanf(fichier2, "%s", &motsauv);
  33.         printf ("%s\n", motsauv);
  34.         printf("debug2" );
  35.         if (i==reussite)
  36.         {
  37.             *copyok=1;
  38.         }
  39.         fclose(fichier);
  40.         fclose(fichier2);
  41.     }

n°2095135
gilou
Modérateur
Modzilla
Posté le 14-08-2011 à 11:54:30  profilanswer
 

Citation :

fprintf(fichier2,copylettre);

 :heink: WTF!

 

De toute façon, il y a pas que ça de pas bon dans ce code:
int testlettre(char *copylettre, int *copyok)
1) tu utilises jamais le fait que copylettre est un pointeur, puisque tu déplaces jamais ce pointeur ni ne modifies la valeur pointée. Alors autant faire un passage de la lettre par valeur: int testlettre(char copylettre, int *copyok), c'est pas plus couteux que de la passer par pointeur, et plus sur.
2) apparemment, ta fonctions ne retourne rien, et tu as un pointeur sur un flag que tu positionnes si tout a été OK.
La encore, ce n'est pas un bon style. Fais retourner à ta fonction un indicateur si tout a été OK:
int testlettre(char copylettre)
{
    int copyok = 0;
    ...............
    return copyok;
}

 

A+,

Message cité 1 fois
Message édité par gilou le 14-08-2011 à 11:54:45

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2095136
showbas
Posté le 14-08-2011 à 12:11:34  profilanswer
 

gilou a écrit :

Citation :

fprintf(fichier2,copylettre);

 :heink: WTF!
 
De toute façon, il y a pas que ça de pas bon dans ce code:
int testlettre(char *copylettre, int *copyok)
1) tu utilises jamais le fait que copylettre est un pointeur, puisque tu déplaces jamais ce pointeur ni ne modifies la valeur pointée. Alors autant faire un passage de la lettre par valeur: int testlettre(char copylettre, int *copyok), c'est pas plus couteux que de la passer par pointeur, et plus sur.
2) apparemment, ta fonctions ne retourne rien, et tu as un pointeur sur un flag que tu positionnes si tout a été OK.
La encore, ce n'est pas un bon style. Fais retourner à ta fonction un indicateur si tout a été OK:
int testlettre(char copylettre)  
{
    int copyok = 0;
    ...............
    return copyok;
}
 
A+,


 
Merci c'est corrigé et étrangement maintenant ça ne crash plus cependant ça ne m'affiche rien comme si le fscanf m'affichait du vide pourtant mon fichier 2 est bien remplit par un mot.

mood
Publicité
Posté le 14-08-2011 à 12:11:34  profilanswer
 

n°2095138
gilou
Modérateur
Modzilla
Posté le 14-08-2011 à 12:16:08  profilanswer
 

Ben déjà, c'est sur qu'en faisant fichier2 = fopen("sauv.txt", "r" ); il va être très facile d'écrire dans fichier2  [:prozac]  
Ensuite, si vous êtes positionné en fin de fichier, c'est sur qu'il y a rien a lire, et que fscanf ne va donc rien trouver à lire.
A+,

Message cité 1 fois
Message édité par gilou le 14-08-2011 à 12:18:48

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2095139
showbas
Posté le 14-08-2011 à 12:17:47  profilanswer
 

gilou a écrit :

Ben déjà, c'est sur qu'en faisant fichier2 = fopen("sauv.txt", "r" ); il va être très facile d'écrire dans fichier2  [:prozac]  
A+,


 :pt1cable: oui effectivement petite erreur de ma part ^^ du coup ça se remet a crasher  :sweat:

n°2095140
gilou
Modérateur
Modzilla
Posté le 14-08-2011 à 12:20:50  profilanswer
 

cf mon édit...
regarder votre position dans le fichier avant écriture et lecture.
l'utilisation de ftell et fpos peut être un plus :whistle:  
Bon, je vais bouffer...
A+,

Message cité 1 fois
Message édité par gilou le 14-08-2011 à 12:31:17

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2095144
showbas
Posté le 14-08-2011 à 13:14:10  profilanswer
 

gilou a écrit :

cf mon édit...
regarder votre position dans le fichier avant écriture et lecture.
l'utilisation de ftell et fpos peut être un plus :whistle:  
Bon, je vais bouffer...
A+,


Super merci bien. j'ai utilisé rewind(fichier2) maintenant ça ne crashe plus par contre encore un probleme (eh oui !) il ne m'affiche que la premiere lettre du mot genre j'ai "salut" dans fichier il ne m'affiche que "s"  :??:  
Pourtant j'ai bien %s.

Code :
  1. rewind(fichier2);
  2. fscanf(fichier2, "%s", &motsauv);
  3. printf ("%s\n", motsauv);

n°2095150
gilou
Modérateur
Modzilla
Posté le 14-08-2011 à 13:58:46  profilanswer
 

Faut dire que dans ton code, il y a des caractereSauv = fgetc(fichier2); qui me semblent suspicieux.
 
Si tu expliquais clairement ce que testlettre est censé faire ça aiderait grandement à comprendre le code.
1) En entrée, fichier contient quoi, fichier2 contient quoi
2) copylettre c'est quoi
3) la fonction fait quoi avec tout ça
4) en sortie fichier contient quoi, fichier2 contient quoi, copylettre vaut quoi et la fonction testlettre  retourne quoi?
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2095157
showbas
Posté le 14-08-2011 à 14:14:56  profilanswer
 

gilou a écrit :

Faut dire que dans ton code, il y a des caractereSauv = fgetc(fichier2); qui me semblent suspicieux.
 
Si tu expliquais clairement ce que testlettre est censé faire ça aiderait grandement à comprendre le code.
1) En entrée, fichier contient quoi, fichier2 contient quoi
2) copylettre c'est quoi
3) la fonction fait quoi avec tout ça
4) en sortie fichier contient quoi, fichier2 contient quoi, copylettre vaut quoi et la fonction testlettre  retourne quoi?
 
A+,


En fait ça serait un peu long et inutile de t'expliquer je pense que le plus important est que a la sortie du while fichier 2 contient un mot entier (du style "salut" ) et le problème est que le fscanf ne prend que la première lettre. J'ai bien vérifié ne t’inquiète pas a la sortie du while le fichier sauv.txt (fichier2 pointe dessus) contient bien un mot entier.
Merci

n°2095159
gilou
Modérateur
Modzilla
Posté le 14-08-2011 à 14:35:56  profilanswer
 

Citation :

En fait ça serait un peu long et inutile de t'expliquer

Dans ces conditions, il est long et inutile que je réfléchisse.
Les programmes non documentés méritent pas d'être améliorés.
Ce sera donc mon dernier commentaire:
Vu que tu as déclaré
char motsauv[1024];
faire
fscanf(fichier2, "%s", motsauv);
devrait améliorer les choses.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2095160
showbas
Posté le 14-08-2011 à 14:48:23  profilanswer
 

gilou a écrit :

Citation :

En fait ça serait un peu long et inutile de t'expliquer

Dans ces conditions, il est long et inutile que je réfléchisse.
Les programmes non documentés méritent pas d'être améliorés.
Ce sera donc mon dernier commentaire:
Vu que tu as déclaré
char motsauv[1024];
faire
fscanf(fichier2, "%s", motsauv);
devrait améliorer les choses.
A+,


Ok je disais pas ça méchamment après si tu le prends comme ça tant pis... c'est simplement que mon programme est un peu compliqué vu que je commence le C c'est pas super compréhensible.
Merci quand même, même si le fait d'enlever le & n'a rien changé.

n°2095164
gilou
Modérateur
Modzilla
Posté le 14-08-2011 à 15:12:45  profilanswer
 

Chez moi, ça marche, quand je lis dans un fichier ou un mot a été inscrit, hein...

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main(int argc, char *argv[])
  4. {
  5.     FILE *f = NULL;
  6.     char *fname = "test.txt";
  7.     char *errtab[3] = {"", "Error opening file %s!\n", "Error scanning file %s!\n"};
  8.     int   errcode = 0;
  9.     if (!(f = fopen(fname, "r" ))) { fprintf(stderr, errtab[errcode = 1], fname); }
  10.     else {
  11.         char buffer[1024] = {0};
  12.         if (fscanf(f, "%1023s", buffer) == EOF) { fprintf(stderr, errtab[errcode = 2], fname); }
  13.         else { fprintf(stdout, "%s\n", buffer); }
  14.         fclose(f);
  15.     }
  16.     return (errcode?EXIT_FAILURE:EXIT_SUCCESS);
  17. }

Donc si ça marche pas chez vous, c'est que le code que vous montrez n'est pas exactement celui que l'on teste ici.
Incidemment, file2 est bien ouvert en écriture et lecture (r+), j’espère...
A+,


Message édité par gilou le 14-08-2011 à 16:05:55

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] Problème fscanf avec string

 

Sujets relatifs
probleme instalation open modelSphere3,1probleme de dessin du mcd
[FLASH] Problème de mise en forme du texteGoogle Maps - problème infobox sous IE
probleme requete sql jointure entre les tablesenlever les espaces au milieu d'un string
[C] : Problème avec la fonction systemProblème Allopass
xsl problème de recuperation de valeurProblème boucle VBA
Plus de sujets relatifs à : [C] Problème fscanf avec string


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR