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 :

problème fscanf et espace


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2012
    Messages : 16
    Par défaut problème fscanf et espace
    Salut, dans le cadre d'un mini projet je rencontre un soucis avec fscanf et l'écriture lecture fichier;

    je m'explique;
    1) j'encode mes éléments dans un tableau de structure
    2)j'enregistre(dans un fichier texte) ces éléments qui sont contenu sous forme d'un tableau de structure à l'aide d'une boucle et de;


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    fprintf(fichier,"%-20s %-10.2f %-10d",alimentation[i].nom,alimentation[i].prix,alimentation[i].stock);
    fprintf(fichier,"\n");
    ce qui me donne par exemple dans mon fichier;



    On peut voir que chaque nom a bien un nombre de digit égal a 20 et un alignement à gauche(%-20s)
    ainsi que le prix et le stock on également un nombre de digit réservés correspondant à ceux que j'ai entrés dans la fonction fprint.

    Jusque là pas de soucis.

    Lorsque je désire récupérer ces données à l'aide d'un fscanf, je fais;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fscanf(fichier,"%s %lf %d",alimentation[i].nom,&alimentation[i].prix,&alimentation[i].stock);
    cette méthode marchera si les noms ne comporte pas d'espace, par contre lorsqu'il y a un espace entres les noms(ex;pomme rouge)ça ne va plus, j'ai essayé plusieurs méthodes tel que;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fscanf(fichier,"%19[^\n] %lf %d",alimentation[i].nom,&alimentation[i].prix,&alimentation[i].stock);
    .
    .
    .

    Mais je rencontre toujours des soucis. :euh:

    Je sais que la fonction fscanf et comme scanf et s’arrête au caractère d'espacement.

    Je sais qu'on peut inclure ces caractères d'espacement+aussi définir combien de digit vont être lu mais je n'arrive pas à mettre cela en place car je ne comprends pas exactement comment procéder.

    Sans oublier que dans mon fichier j'ai un caractère blanc("%-20s %-10.2f %-10d") qui n'est pas compris dans la chaine et qui est un séparateur entre le nom le prix et le stock.

    Cela fait 2 jour que je cherche mais je n'ai pas trouvé la solution

    merci

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Il vaut mieux passer par un fgets pour lire la ligne en entier.

    Ensuite tu lis tout ce qui précède le premier '\t' et tu le met dans une chaine de caractère.

    Tu lis tout le reste jusqu'au prochain '\t' et tu le met dans une chaine de caractère etc...

    Et ensuite tu utilise les fonction strof et stroi (je ne suis pas sûr des noms) pour obtenir un int ou un float à partir des chaines de caractères.

    Mais le plus simple aurait été de mettre la chaines de caractère à la toute fin de ta ligne comme cela tu n'as plus qu'à :
    - lire tes int/float etc... avec fscanf
    - lire ta chaine de caractère avec fgets (/!\\ ne pas oublier qu'il mettra le '\n' à la fin de ta chaine)

  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Le problème est que alimentation[i].nom va se retrouver avec la chaine complètée avec des blancs, pour faire les 19 caractères, et qu'il faut supprimer ces blancs excédentaires.
    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(p = alimentation[i].nom+18; isspace(*p); p--)*p = 0;

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2012
    Messages : 16
    Par défaut
    oula je m'embrouille là

    Car notre prof nous avez montré la facilité de fprintf et fscanf pour écrire et lire un fichier avec des champs constants(nombre de digit prédéfinis qui en même temps se marie bien avec les structures).

    Mais voilà qu'il n'a pas parlé des espaces....

    Est ce qu'il n'y a pas un autre moyen de procéder tout en gardant le principe de la méthode qui marche super bien quand il n'y pas d'espace, je ne connais pas très bien fscanf mais n'y aurait-il pas moyen de faire par exemple;

    1) supprimer les espaces entre les différents champ à l'écriture du fichier
    ça;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fprintf(fichier,"%-20s %-10.2f %-10d",alimentation[i].nom,alimentation[i].prix,alimentation[i].stock);
    deviendrait;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fprintf(fichier,"%-20s%-10.2f%-10d",alimentation[i].nom,alimentation[i].prix,alimentation[i].stock);
    2) par exemple modifier fscanf afin que les espace blancs sont pris en compte, que la lecture s'arrete au prochain champ qui est un nombre ;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fscanf(fichier,"%20[^0123456789]%lf%d",alimentation[i].nom,&alimentation[i].prix,&alimentation[i].stock);
    Et ne pas avoir recours à d'autres fonctions?

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    1) Supprimer les espaces entre les différents champ à l'écriture du fichier
    ne changera rien : le %-20s complètera avec des blancs.

    2) par exemple modifier fscanf afin que les espace blancs sont pris en compte, que la lecture s'arrete au prochain champ qui est un nombre ;
    Cela interdit que ces caractères soient présents dans le nom. De plus, il faut prévoir tous les cas de figure possibles : un nombre peut aussi commencer par un . , +, -, ... On aura toujours de toute façon les blancs excédentaires en queue du nom.

    3) Une possibilité est de placer un séparateur derriere le champ nom dans le fichier.
    Par exemple, le fichier peut être créé par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      len = strlen(alimentation[i].nom);
      fprintf(fichier,"%s.%*c%-10.2f%-10d\n",alimentation[i].nom,19-len,' ', alimentation[i].prix, alimentation[i].stock );
    Le fichier contient alors des lignes comme celles-ci :
    patate.             45.00     250       <\n>
    pomme rouge.        250.00    45        <\n>
    Il peut être relu simplement avec le format "%[^.].%lf%d"

  6. #6
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Salut,

    dans ce cas le fichier contient des données de longueur fixe. Il "suffit" donc de récupérer des chaines de longueur fixe et de le transformer adéquatement.

    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
     
     
    char nom_fic[21];   // longueur du printf +1 pour le zero terminal
    char prix_fic[11];  // id
    char stock_fic[11]; // id
     
    ....
     
    fscanf(fichier, "%20c%10c%10c", nom_fic, prix_fic, stock_fic);
    nom_fic[20]=0; // pour s'assurer qu'il y a un 0 terminal
    prix_fic[10]=0;
    stock_fic[10]=0;
     
    // trim est une fonction qui vire les espaces à droite cf post de diogene
    // et éventuellement ceux à gauche
    alimentation[i].nom=strdup(trim(nom_fic));
    alimentation[i].prix=atof(prix_fic);
    alimentation[i].stock=atoi(stock_fic);
     
    ...
    EDIT: il faudra évidemment rajouter tout ce qui est gestion d'erreurs ...
    Petite erreur dans le code corrigée.
    Une autre version pourrait lire directement le réel et l'entier avec un %10f%10d dans le format.

Discussions similaires

  1. Problème avec les espaces dans un tableau !
    Par remixtech dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 10/07/2006, 19h30
  2. Problème de menu: espaces entre les images
    Par nmathon dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 30/05/2006, 14h16
  3. [Winsock] Problème avec les espaces
    Par Fiquet dans le forum Développement
    Réponses: 3
    Dernier message: 12/01/2006, 18h06
  4. [XSL] problème avec copy espace de nom
    Par luta dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 11/10/2005, 15h18
  5. Problème Locate avec espaces
    Par Clezio dans le forum Bases de données
    Réponses: 2
    Dernier message: 10/03/2004, 19h06

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