IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Probleme avec fscanf.


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Par défaut Probleme avec fscanf.
    Bonjour,

    J'essaye d'écrire un lecteur de fichier afin de faciliter la rentré d'information et leur modification.

    Seulement il y a un élément qui m'échappe et que je n'arrive pas à élucider.

    mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main(int argc, char* argv[]){
    	FILE* FScript = NULL ;
    	char command[32] ;
    	char nom[32] ;
     
    	//ouverture du fichier
    	if ((FScript = fopen("Animation.script","r")) == NULL){
    		printf("Erreur ouverture de fichier impossible \n");
    		exit(1);
    	}
     
    	//saute les caracteres jusqu'au ':' puis le saute à son tour
    	fscanf(FScript,"%s %*[^:] %*[: ]",command);
     
           //test si le premier mot est nom 
    	if (strcmp(command,"nom") == 0) {
       	fscanf(FScript,"%50[^\n]",nom);
               //si c'est le cas on scan le nom se situant apres les deux points.
    		printf("nom : %s \n",nom);
    	}
    	else {
    		printf("Erreur commande \n");
    		exit(1);
    	}
     
    	return EXIT_SUCCESS ;
    }
    Et dans le fichier Animation.script :
    Resultat apres compilation :
    $ ./test.out
    nom : : le chat botte
    Le problème est que mon Fscanf est sensé avoir sauté les deux points. Mais pourtant ce n'est pas le cas. De plus si je transforme ma ligne dans Animation.script en :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nom animation : le chat botte
    Alors comme par magie, la variable nom me renverra bien ce qu'il y a après les deux points.

    Si quelqu'un pouvait m'aider et surtout m'éclaircir sur ce phénomène.

    Merci.

  2. #2
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Avec comme chaîne de format:
    scanf va lire le premier mot et le stocker dans l'argument suivant (command). Puis elle va vouloir lire des caractères autres que ':'. Mais dans votre fichier:
    , il n'y a qu'un espace entre le premier mot ("nom") et le ':'; or, scanf saute les espaces, sauts de ligne, etc..., qu'elle considère juste comme des séparateurs. Je pense donc que le premier scanf s'arrête là, ne trouvant pas de mot non vide et ne contenant pas ':'. Le second scanf lit ce qui reste sur la ligne.
    Je pense que le format correct doit être dans votre cas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    "%s %*[:]"
    ou
    "%s :"
    , en supposant qu'il n'y a qu'un seul mot avant le ':'. Il y a encore plus simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fscanf(FScript,"%s : %50[^\n]",command,nom);
    Je tiens à préciser que je n'ai pas testé le fonctionnement de ces bouts de code, donc je ne garantis pas que je ne me suis pas trompé.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Par défaut
    Le problème est qu'avant les ':' il y a un ou plusieurs mot pour rendre le fichier plus lisible.
    Mais au vu de ce que vous m'avez dit que les caractères d'échappements, j'ai testé comme solution :
    Avec dans le script :
    Resultat :
    nom : : le chat botte
    Et avec dans le script :
    nom animation : le chat botte
    J'ai pour résultat :
    nom : : le chat botte
    Dans le second cas il a bien sauté le mot animation mais comme dans le premier cas, il n'a pas l'air de m'avoir mangé tous les caracteres jusqu'au deux points mais il s'arrête au niveau de l'espace alors que je lui dis de me les manger avec
    %*[ ] %*[: ]
    .

    Mais merci de votre aider.

  4. #4
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Je ne suis pas sûr que "%*[ ]" soit valide, car comme je vous l'ai expliqué, les espaces font partie des caractères que scanf traite comme des séparateurs; ainsi, je ne crois pas dire de bêtise en disant que pour scanf, 1, 2, 3, ou N espaces, c'est la même chose.
    Je ne pense pas qu'il soit possible de s'en sortir simplement avec une seule chaîne de format si l'on peut avoir plusieurs mots avant le ':'. En revanche, ceci devrait fonctionner:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int c;
     
    ...
    fscanf(FScript,"%s",command);
    while ((c=getc(FScript))!=':' && c!=EOF);
    fscanf("%50[^\n]",nom);

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    char *p=NULL, *p0=NULL, *Debut=NULL ;
    char  Chaine_Debut[256] ;
    char  Chaine_Fin[256] ;
     
    .......
     
    p = strchr ( command, ':' );
    if ( p != NULL )
    {
        Debut = p ;
     
        for ( ; ; )
         {
            p0 = strchr ( (p+1), ':' );
            if ( p0 == NULL )
              break ;
            p = p0 ;
         }
     
       Fin = p ;
       *Debut = '\0' ;
     
       sscanf ( command, "%s", Chaine_Debut );
       sscanf ( (Fin+1), "%s", Chaine_Fin );
     
      *Debut = ':' ;
    }
    else
         fprintf ( stderr, "Mauvaise ligne %s",command);

  6. #6
    Membre émérite
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Par défaut
    Solution "simple" si tu ne veux pas tout modifier...:
    (l'explication fournie par stephl étant la bonne)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define DELIM ":"
     
    int main(int argc, char* argv[]){
      FILE* FScript = NULL ;
      char command[32] ;
      char nom[32] ;
     
      /* ouverture du fichier */
      if ((FScript = fopen("Animation.script","r")) == NULL){
        printf("Erreur ouverture de fichier impossible \n");
        exit(1);
      }
     
      /* saute les caracteres jusqu'au ':' puis le saute à son tour */
      fscanf(FScript,"%s %*[^"DELIM"]",command);
     
      /*   test si le premier mot est nom  */
      if (strcmp(command,"nom") == 0) {
        fscanf(FScript, DELIM" %50[^\n]",nom);
        /*     si c'est le cas on scan le nom se situant apres les deux points. */
        printf("nom : %s \n",nom);
      }
      else {
        printf("Erreur commande \n");
        exit(1);
      }
     
      return EXIT_SUCCESS ;
    }
    Mais attention à l'utilisation de *scanf si tu souhaites mettre ce genre de code dans une boucle...
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 168
    Par défaut
    Merci, je viens de finir de coder et tout roule impeccablement.
    J'ai dû combiner les deux techniques car j'avais une boucle dans mon script pour charger des chemins.

    Merci encore !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probleme avec fonction fscanf
    Par Meach dans le forum C
    Réponses: 6
    Dernier message: 25/06/2007, 18h50
  2. Réponses: 2
    Dernier message: 26/04/2007, 20h27
  3. probleme avec fscanf
    Par vivh349 dans le forum C++
    Réponses: 6
    Dernier message: 07/08/2006, 17h13
  4. Probleme avec fseek
    Par Bjorn dans le forum C
    Réponses: 5
    Dernier message: 04/08/2002, 07h17
  5. [Kylix] probleme avec un imagelist
    Par NicoLinux dans le forum EDI
    Réponses: 4
    Dernier message: 08/06/2002, 23h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo