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 :

Récupération des informations contenues dans un fichier


Sujet :

C

  1. #1
    Membre habitué Avatar de dream_of_australia
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 167
    Points : 136
    Points
    136
    Par défaut Récupération des informations contenues dans un fichier
    J'essaie de récupérer certaines informations depuis un fichier, ligne par ligne. Le traitement dépend du premier caractère de la ligne.
    J'ai des lignes de la forme "lettre double double double" que je dois traiter.
    J'ai essayé pas mal de choses mais je suis toujours coincée.
    Je ne récupère que des double égaux à 0 (ce qui veut dire que la transformation atof ne s'est pas bien passée).

    Voici 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
    char *file = AG_STRING(1);
        FILE *f ;
        char line[LINE_MAX] ; char tabtmp[10] ; 
        double sommets[MAXSIZE][3] ;
        int i = 0, j = 0, k = 0, nbSommets = 0 ;
     
        if ((f = fopen(file, "r")) != NULL) {
               while (fgets(line, LINE_MAX, f) != NULL) {
                     i = 0 ;
                     if (line[i] == '#') { skipLine(f) ; }
                     else if (line[i] == 'v') {
                        i = 1 ;
                        for (k=0 ; k<3 ; k++) {
                            j = 0 ;
                            while (&line[i] != " ") { i++ ; } // on avance
                            while (&line[i] != " ") {   // on copie
                                tabtmp[j] = line[i] ; 
                                 i++ ; j++ ; 
                            }
                            tabtmp[j] = '\0' ; // fin de chaine
                            sommets[nbSommets][k] = atof(tabtmp) ; // conversion
                            tabtmp[0] = '\0' ; // chaine vide
                            nbSommets++ ;
                        }
                     }
               }                                                           
              fclose(f) ;                               
        }

    Je voudrais un conseil pour m'aider à avancer ou bien une toute nouvelle piste si celle que j'ai suivie n'est pas la bonne.

    J'ai essayé pas mal de choses (fscanf et autres) mais je n'arrive à rien!

    Merci !

  2. #2
    Invité
    Invité(e)
    Par défaut
    Salut

    A quoi sert la première lettre ? Et lesquelles sont valides ? Et à quoi ressemble un fichier type ?

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (&line[i] != " ")
    Ce code est très douteux et ne marchera pas. Ici, tu ne compares pas deux caractères mais tu compares deux adresses, celle où est stocké le caractère dans le tableau et celle où est stocké un espace (qui correspond en fait à une chaîne littérale, située ailleurs en mémoire). La condition sera toujours vraie (opérateur != ). Ce code doit en principe provoquer une boucle infinie.

  4. #4
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 28
    Points : 24
    Points
    24
    Par défaut Ton descripteur
    C'est quoi la variable que tu utilises comme descripteur de fichier car
    j'ai vu une declaration et ton plus bas tu mets je ne vois pas la chaine qui correspond au variable file.

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    @sambalien:
    • FILE* est le type "fichier ouvert" du C standard. La structure pointée contient typiquement un descripteur de fichier tel qu'on le connait sous POSIX.
    • f est une variable de ce type, initialisée avec le retour de fopen().
    • file est une variable de type char*, initialisée avec l'expression AG_STRING(1). Aucune idée de ce qu'il y a derrière cette macro.


    @dream_of_australia : Peut-on voir le code de la fonction skipline() ? Vue son interface, je pense qu'elle est bugguée.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    déjà, pourquoi faire simple quand on peut faire compliqué

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
                while (fgets(line, LINE_MAX, f) != NULL) {
                    if ( line[0] == 'v') {
                    }
                }
    suffit à tout passer et ne traiter que les bonnes lignes.

    Ensuite, une solution simple et portable suffit pour lire la ligne (à moins que tu aies C99, auquel cas c'est encore plus simple) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    float f[3] ;
    char c ;
     
    ....
     
    sscanf ( line, "%c %f %f %f", &c, &f[0], &f[1], &f[2]);
    for ( i = 0 ; i < 3 ; i++)
        sommets[nbSommets][i] = f ;
    Si tu bénéficies du format lf, tu peux directement lire tes sommets :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char c ;
     
    ....
     
    sscanf ( line, "%c %lf %lf %lf", &c, &sommets[nbSommets][0], 
               &sommets[nbSommets][1], &sommets[nbSommets][2]);
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  7. #7
    Membre habitué Avatar de dream_of_australia
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 167
    Points : 136
    Points
    136
    Par défaut
    Merci pour toutes ces réponses !

    @souviron : j'ai lu plusieurs articles déconseillant l'utilisation du scanf, qui apparemment peut tout faire planter.

    @medinoc : j'avais effectivement de mon côté viré l'appel à skipline

    @jeroman : cette comparaison fonctionne, quand tu mets & devant une variable tu travailles sur sa valeur et non son adresse. (si j'ai bien tout compris !!)

    Tout fonctionne, en fait j'avais un problème à l'affichage du test, car je travaille avec une bibli qui n'utilise pas le formatage standard du C (les %d, %i, %f...). J'ai un peu amélioré ma fonction mais dans le principe c'est bon.

  8. #8
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par dream_of_australia Voir le message
    @souviron : j'ai lu plusieurs articles déconseillant l'utilisation du scanf, qui apparemment peut tout faire planter.
    Eventuellement si on ne sait pas prévoir correctement la taille de ses buffers, mais c'est scanf dont tu parles, qui est pour la saisie à l'écran, et il y a des manières de faire (voir sur ce forum même).

    Le sscanf est d'une utilisation tout à fait sûre...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  9. #9
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    ...
    @jeroman : cette comparaison fonctionne, quand tu mets & devant une variable tu travailles sur sa valeur et non son adresse. (si j'ai bien tout compris !!)
    ...
    Absolument pas et jeroman a raison. Si tu mets & devant l'identificateur d'une variable, tu obtiens l'ADRESSE de la variable.
    Cette comparaison ne fonctionne pas. elle devrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                            while (line[i] != ' ') { i++ ; } // on avance
                            while (line[i] != ' ') {   // on copie
    Ce code est à l'évidence illogique. Je suppose que ce code devrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                            while (line[i] == ' ') { i++ ; } // on avance
                            while (line[i] != ' ') {   // on copie
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  10. #10
    Membre habitué Avatar de dream_of_australia
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 167
    Points : 136
    Points
    136
    Par défaut
    Oui pardon j'ai répondu vite fait mais en fait j'avais changé ça (comme je l'ai dit j'ai un peu retouché ma fonction).

    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
    if ((f = fopen(file, "r")) != NULL) {
               while (fgets(line, LINE_MAX, f) != NULL) {
                    ........
                     else if (line[0] == 'v' && line[1] == ' ') {
                        i = 1 ;
                        for (k=0 ; k<3 ; k++) {
                            while (line[i] == ' ') { i++ ; }
                            marqueur = i ;
                            while (line[i] != ' ' && line[i] != '\n') { i++ ; } 
                            sommets[nbSommets][k] = (GLfloat) atof((char const *) (substr(line, marqueur, i-1))) ;
                        }
                        nbSommets++ ;
                     }
                     ........
               }
               fclose(f) ;
               ..............
    Merci à tous !

  11. #11
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 28
    Points : 24
    Points
    24
    Par défaut publie ton code
    bonjour a tous,
    dream_of_australia: j'aimerais que tu publie ton code au complet si tu ne vois pas d'inconvénients. Pourrais-tu nous dire également où dans le code tu as buggé. Merci.

  12. #12
    Membre habitué Avatar de dream_of_australia
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 167
    Points : 136
    Points
    136
    Par défaut
    Les utilisateurs ont relevé mes erreurs au cours de cette discussion. Merci à tous d'ailleurs!

    Quant au code complet, je pense qu'il apporterait plus de confusion qu'autre chose étant donné que j'utilise des bibliothèques et qu'il y a des appels et des variables spécifiques à ces biblis que j'utilise partout.

    As-tu une question spécifique, un point sur lequel je pourrais te renseigner ?

  13. #13
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 28
    Points : 24
    Points
    24
    Par défaut lecture de code
    ce que je veux ce n'est pas vraiment le tester mais ce de le lire et de voir si je comprends a quoi sert ton programme, si tu trouves que ca te derange je n'y ai aucun probleme

  14. #14
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    en tous cas, je ré-itère que tu réinventes la roue..


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
                        i = 1 ;
                        for (k=0 ; k<3 ; k++) {
                            while (line[i] == ' ') { i++ ; }
                            marqueur = i ;
                            while (line[i] != ' ' && line[i] != '\n') { i++ ; } 
                            sommets[nbSommets][k] = (GLfloat) atof((char const *) (substr(line, marqueur, i-1))) ;
                        }
                        nbSommets++ ;
    est avantageusement remplacé par :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                        sscanf ( &(line[1]), "%lf %lf %lf", 
                                 &(sommets[nbSommets][0]),
                                 &(sommets[nbSommets][1]),
                                 &(sommets[nbSommets][2]));
     
                        nbSommets++ ;
    et est du C plus correct...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  15. #15
    Membre habitué Avatar de dream_of_australia
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 167
    Points : 136
    Points
    136
    Par défaut
    @sambalien : j'ai moi-même passé 15 jours à décortiquer les apis des biblis... Je ne vois pas trop l'intérêt pour comprendre le concept de la boucle de lecture d'un fichier de mettre 500 lignes de code... Par contre si quelque chose n'est pas clair pour toi dans la fonction exposée ici je serais ravie de te répondre.

    @souviron : oui sûrement ,
    1 je ne connais pas d'avance le nombre d'éléments contenus dans chaque ligne (pour un autre cas if qui n'est pas présenté ic), scanf fonctionne-t-il dans ce cas ?
    2 j'ai une bibli qui n'utilise pas le formatage standard en C (les lettres %d %fl etc...) et je voudrais éviter de m'emmêler les pinceaux...
    3 est-ce que scanf est plus performant en termes d'utilisation mémoire et de temps d'exécution ?

    j'ai essayé de mettre ton code avec scanf dans le if où il n'y a toujours que 3 éléments par ligne, mais il ne fonctionne pas (je ne récupère que des 0...).

  16. #16
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par dream_of_australia Voir le message
    @sambalien : j'ai moi-même passé 15 jours à décortiquer les apis des biblis... Je ne vois pas trop l'intérêt pour comprendre le concept de la boucle de lecture d'un fichier de mettre 500 lignes de code... Par contre si quelque chose n'est pas clair pour toi dans la fonction exposée ici je serais ravie de te répondre.

    @souviron : oui sûrement ,
    1 je ne connais pas d'avance le nombre d'éléments contenus dans chaque ligne (pour un autre cas if qui n'est pas présenté ic), scanf fonctionne-t-il dans ce cas ?
    2 j'ai une bibli qui n'utilise pas le formatage standard en C (les lettres %d %fl etc...) et je voudrais éviter de m'emmêler les pinceaux...
    3 est-ce que scanf est plus performant en termes d'utilisation mémoire et de temps d'exécution ?
    strtok ou strstr ou strchr et sscanf sont standards....

    Comme je dis, libre à toi de réinventer le fil à couper le beurre...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  17. #17
    Membre habitué Avatar de dream_of_australia
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2007
    Messages : 167
    Points : 136
    Points
    136
    Par défaut
    Je n'ai pas dit que scanf n'était pas standard, j'ai simplement dit que j'utilise une bibli qui n'utilise pas le formatage standard (les %d, %c etc... sont différents) et que j'ai peur de m'emmêler entre des appels avec ce formatage non standard (et j'en ai beaucoup dans mon code) et des appels avec le formatage standard au milieu.

    Merci pour ton aide en tout cas

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

Discussions similaires

  1. Lecture des informations contenues dans les fichiers CDA de Windows
    Par DelphiCool dans le forum Codes sources à télécharger
    Réponses: 0
    Dernier message: 03/02/2013, 12h53
  2. Sauver et restaurer des informations contenues dans un fichier
    Par lilimilou29 dans le forum Général Dotnet
    Réponses: 1
    Dernier message: 14/06/2007, 20h08
  3. Utiliser des fonctions contenues dans un fichier .bas
    Par usbeck dans le forum Visual C++
    Réponses: 4
    Dernier message: 11/08/2006, 12h03
  4. Réponses: 5
    Dernier message: 16/03/2005, 22h17
  5. Réponses: 2
    Dernier message: 20/02/2004, 08h47

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