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 :

lecture de mon fichier de donnees initiales


Sujet :

C

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut lecture de mon fichier de donnees initiales
    Bonjour, je désire me faire un fichier txt qui contienne toutes mes donnees de mon pb et ensuite je veux faire une fonction qui lira ce fichier et remplira des tableaux. Voici tout d'abord un exemple de mon fichier d'entrées (input.txt) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    TEMP 350 400 450
    PRES 1.5 1.7 1.6
    EGR 20 30 45
    RICHESSE 0.6 0.5 0.4
    Là où je bloque est dans la lecture d'une ligne pour être plus précis. je vous envoie la partie qui bug :

    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
     
    file=fopen(input_file,"r");
    while( !feof(file) && (fgets (line, sizeof line, file) != NULL) )
    {
    /* suppression du caractère '\n' */
    char * p = strchr(line, '\n'); 
    if (p != NULL)
    *p = 0;
     
    /* lecture ligne par ligne et on remplit les tableaux correspondant au mot clé lu */
    if(strstr(line,"TEMP ")!=NULL)
    {
    char * keyword=NULL;
    fscanf(file,"%s",keyword);  <-- ici ca bug
    for(i=0;i<*N;++i)
    fscanf(file,"%lf",&temp[i]);
     
    blabla ...
    }
    J'ai avant testé l'ouverture du fichier, créer mes tableaux avec malloc etc.

    line est défini comme suit

    et c'est dans ce tableau que sera mis le résultat de fgets. En fait, je veux lire les trois nombres après TEMP et les mettre dans mon tableau temp. Pouvez-vous me donner un petit coup de pouce s'il vous plait. Une fois que ca marchera pour TEMP, je répèterai le même algo pour PRES et les autres mots clés.

    Merci.

  2. #2
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(strstr(line,"TEMP ")!=NULL) 
    { 
    char * keyword=NULL; 
    fscanf(file,"%s",keyword);  <-- ici ca bug
    Normal : tu n'as pas réservé de place pour stocker la chaîne de caractères. Pour stocker une chaîne, il faut un tableau de char or keyword est un pointeur (sur char) pas un tableau de char.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Salut, merci de ta réponse. Ca marche mieux. Mais maintenant mon pb s'est décallé dans la lecture de la ligne. Il me lit une mauvaise ligne. J'ai donc modifié mon code comme ceci :

    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
     
    while( !feof(file) && (fgets (line, sizeof line, file) != NULL) )
    {
    printf("line = %s\n",line);
     
    char * p = strchr(line, '\n');
    if (p != NULL)
    *p = 0;
     
    char keyword[50]; /* tableau stockant le mot cle */
     
    if(strstr(line,"TEMP ")!=NULL)
    {
    printf("je suis dans la temperature\n");
    fscanf(file,"%s",keyword);
    printf("keyword = %s\n",keyword);
    for(i=0;i<*N;++i)
    fscanf(file,"%lf",&temp[i]);
     
    for(i=0;i<*N;++i)
    printf("%g\t",temp[i]);
     
    printf("\n");
    }
     
    blabla...
    }
    Ma sortie est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    line = TEMP 350 400 450
     
    je suis dans la temperature
    keyword = PRES
    1.5     1.7     1.6
    line =
    Pourquoi est-ce que mon tableau keyword ne contient pas TEMP mais PRES. Pourquoi est-il passé à la ligne suivante ?

    Merci encore.

  4. #4
    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
    Pourquoi est-il passé à la ligne suivante ?
    Parce que tu lui as dit de continuer à lire le fichier et de mettre la chaîne qu'il trouve dans Keyword. En fait, tu devrais analyser ligne (ou se trouve TEMP)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    while( !feof(file) && (fgets (line, sizeof line, file) != NULL) ) 
    { 
       ....
       char keyword[50]; /* tableau stockant le mot cle */ 
     
       if(strstr(line,"TEMP ")!=NULL) 
       { 
        ....
        fscanf(file,"%s",keyword); // Il lit la suite du fichier et trouve PRES

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut Re: lecture de mon fichier de donnees initiales
    Mes remarques :
    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
     
    file = fopen(input_file, "r");
    /* -ed-
    while( !feof(file) && (fgets (line, sizeof line, file) != NULL) )
     
    Ce feof() ne sert à rien. La fin de fichier est detectee par le controle de la valeur retournee par fgets(), ce qui est correct.
    */
    while ( fgets (line, sizeof line, file) != NULL )
     
    {
       /* suppression du caractère '\n' */
       char * p = strchr(line, '\n');
       if (p != NULL)
          *p = 0;
     
       /* -ed- OK */
     
     
       /* lecture ligne par ligne et on remplit les tableaux correspondant au mot clé lu */
       if (strstr(line, "TEMP ") != NULL)
       {
          char * keyword = NULL;
          fscanf(file, "%s", keyword);     < -- ici ca bug
     
          /* -ed-
          keyword vaut NULL. Il n'y a donc pas d'espace mémoire pour stocker le résultat.
          */
    Une fois que la ligne est lue par fgets(), et identifiée avec strstr(), il faut traiter le reste de la lignenavecn par exemple, sscanf()...

    Ne pas mélanger lecture et traitement. Ne pas utiliser fscanf(), trop difficile à faire correctement.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Salut Emmanuel, j'ai doncmodifié mon code de lamanière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sscanf(line,"%s%lf%lf%lf",keyword,&temp[0],&temp[1],&temp[2]);
    ce code fonctionne parfaitement. Mon tableau temp est bien rempli. Mais j'ai triché, car ici je savais que j'avais 3 éléments. Mais je ne connais pas d'avance le nombre d'éléments de mon tableau. Ce nombre est calculé un peu avant dans ma fonction (je calcule le nombre d'espace de la ligne et ce nombre d'espaces est égal à la taille de mon tableau). J'ai donc voulu utiliser une boucle "for" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    sscanf(line,"%s",keyword); // je lis le mot cle
    for(i=0;i<*N;++i)
    sscanf(line,"%lf",&temp[i]); // je lis les autres nombres
    Or j'obtiens le résultats suivant :

    Je pense que l'erreur provient du fait que je fais deux sscanf pour la même ligne et non un seul. As-tu une solution ?

    Merci.

  7. #7
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom
    j'ai triché, car ici je savais que j'avais 3 éléments. Mais je ne connais pas d'avance le nombre d'éléments de mon tableau.
    Effectivement, si le nombre d'éléments est variable, il ne faut pas utiliser sscanf() qui est fait pour les entrées formattées, mais plutôt une analyse dynamique de la ligne.

    Dans une boucle, chercher le nom du champ avec strstr(), puis convertir avec strtol() ou strtoul(). Une bonne utiisation du 2ème paramètre peut aider. Attention à bien positionner le début de la chaine à analyser.

    Entraine toi sur du code simple :
    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
     
    char sline[] = "TEMP 350 400 450";
     
    char *p = strstr(sline, "TEMP");
     
    if p != NULL)
    {
       p = ...;
     
       while (*p)
       {
          int n = strtol(p, ...);
         printf("%d\n", n);
       }
    }
    A toi de compléter. Sortie attendue :

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Salut Emmanuel, voici mon code qui marche. Mais je trouve qu'il est très compliqué.

    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
     
    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
     
    int main()
    {
     
    char sline[]="TEMP 350 400 450";
     
    char *p = strstr(sline, "TEMP");
     
    char c;
     
    if (p != NULL)
    {
       p = strstr(sline," ");
     
       while (*p)
       {
          int n = strtol(p,c,0);
          printf("n = %d\n",n);
          p = strstr(p+1," ");
          if(p==NULL) break;         
       }
    }
     
    return 0;
    }

  9. #9
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom
    Salut Emmanuel, voici mon code qui marche.
    NON!
    Mais je trouve qu'il est très compliqué.
    Il m'a surtout fait un beau crash ! Il y a peut être des raisons :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Compiling: main.c
    main.c:6: warning: function declaration isn't a prototype
    main.c: In function `main':
    main.c:20: warning: passing arg 2 of `strtol' makes pointer from integer without a cast
    main.c:12: warning: 'c' might be used uninitialized in this function
    Ok, visiblement, tu n'as pas lu ou pas compris la doc de strtol(), alors que j'ai insisté sur ce point et notamment l'usage du 2 ème paramètre

    La correction est simplissime :
    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
     
    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
     
    int main()
    {
       char sline[] = "TEMP 350 400 450";
     
       char *p = strstr(sline, "TEMP");
     
       if (p != NULL)
       {
          p = strstr(sline, " ");
     
          while (*p)
          {
             int n = strtol(p, &p, 0);
             printf("n = %d\n", n);
          }
       }
     
       return 0;
    }

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Re,
    Merci ! Effectivement, ta solution me parait bcp plus sûre que la mienne.
    Merci de ta patience.

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

Discussions similaires

  1. [AC-2007] Mon fichier (*.mdb) en lecture
    Par solaar dans le forum Sécurité
    Réponses: 1
    Dernier message: 20/01/2011, 09h41
  2. Réponses: 2
    Dernier message: 25/10/2007, 13h56
  3. [RegEx] Lecture/transformation de mon fichier texte
    Par charlysquare dans le forum Langage
    Réponses: 4
    Dernier message: 24/04/2006, 14h24
  4. lecture d'éléments dans mon fichier
    Par gillou4 dans le forum C
    Réponses: 9
    Dernier message: 23/10/2005, 16h19

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