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 :

lire des données à partir d'un fichier texte


Sujet :

C

  1. #1
    Membre régulier Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 75
    Points
    75
    Par défaut lire des données à partir d'un fichier texte
    Bonjour,

    Je suis un débutant en c, j'ai plus l'habitude de programmer en MATLAB mais pour le boulot je dois apprendre à programmer en c.

    Donc voilà mon problème : j'ai un fichier texte qui contient une succession de matrice 3*3 comme cela :

    234 236 245
    241 257 234
    245 235 256
    234 236 245
    241 262 234
    245 235 256
    234 236 245
    241 254 234
    245 235 256
    234 236 245
    241 261 234
    245 235 256
    Je veux dans un premier temps récupérer toutes les valeurs centrale de ces matrices, 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
    #include <stdio.h>
    #include <stdlib.h>
     
    #define TEMP_PATH "/home/flaherty/testgnuplot/temp.txt"
     
    int main(void)
    {
      int valeurs[256];
     
      FILE *fid=fopen(TEMP_PATH,"r"); //on ouvre le fichier
      if(NULL == fid) {
    	printf("erreur a l ouverture du fichier...");
    	}
      else {
    	int i, cnt=0;
            char buf[256];
            while(NULL != fgets(buf, sizeof buf, fid)) {  //on lit ligne par ligne le fichier
    	   printf("%s\n",buf);  // on affiche ces lignes
               valeurs[cnt ] = strtol(buf, NULL, 10); 
               ++cnt ;
    	   }
            for(i = 1; i < cnt; i=i+3) { //on récupère les valeurs des lignes centrales des matrices
               printf("%d\n",valeurs[i]);
    	   }
    	printf("%s",buf);
    	}
    }
    Le problème vient de strtol, car il ne me convertit que la première colonne de mes matrices, je pense que cela vient du deuxième argument de cette fonction le NULL (problème d'espace entre les valeurs interprété comme NULL ??).
    Alors qu'en vrai je ne veux pour le moment que la deuxième colonne...

    Ma question est comment utiliser strtol pour qu'il convertissent les chaines de caractères obtenues avec fgets en entier et qu'ils les range dans un tableau à 3 colonnes, x lignes pour que je puisse dans un premier temps récupérer les valeurs de la 2 ème colonne, puis dans un deuxième temps faire la moyenne de toutes la matrices 3*3 ?


    Voilà j'espère que j'ai exposé clairement mon problème.

    Flaherty

  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
    strtol(buf, &end,10) va lire le tableau buf et convertir en long la chaîne obtenue. Cette chaîne est terminée lorsque le caractère n'est plus conforme à la représentation d'un entier décimal et il met alors l'adresse de ce caractère dans end.
    Pour lire les trois valeurs d'une ligne et les mettre, par exemple, dans un tableau val, on peut faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int i;
    long val[3] ; // ou int ; pour une ligne
    long * p = buf;
    for(i =0; i<3;i++) val[i]= strtol(p,&p,10);

  3. #3
    Membre régulier Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 75
    Points
    75
    Par défaut
    Désolé mais ça ne fonctionne pas :

    Quand je mets ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      else {
    	int i;
            char buf[256];
            while(NULL != fgets(buf, sizeof buf, fid)) {
    	   printf("%s\n",buf);
    	   }
    	long * p = buf;
    	for(i =0; i<3;i++) val[i]= strtol(p,&p,10);
    	printf("%ld\n%ld\n%ld\n",val[1],val[2],val[3]);
    	}
    Quand je compile j'ai ce message d'erreur :
    temp.c: In function ‘main’:
    temp.c:20: attention : initialization from incompatible pointer type
    temp.c:21: attention : passing argument 1 of ‘strtol’ from incompatible pointer type
    temp.c:21: attention : passing argument 2 of ‘strtol’ from incompatible pointer type
    alors si je remplace
    par
    Je n'ai plus de problème de compilation mais ça m'affiche :

    0
    0
    -1078300660

  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
    Oui, j'ai écrit par mégarde long *

    Par contre, tu as mis le code à l'extérieur du while, donc tu l'exécutes quand tu es arrivé en fin de fichier !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      else {
    	int i;
               char buf[256];
               while(NULL != fgets(buf, sizeof buf, fid)) {
    	   printf("%s\n",buf);
    	  long * p = buf;
    	  for(i =0; i<3;i++) val[i]= strtol(p,&p,10); // ceci c'est pour une ligne
    	  printf("%ld\n%ld\n%ld\n",val[1],val[2],val[3]);
    	}
            }
    il faut adapter le code et le type du tableau pour lire les 3 valeurs de toutes les lignes dans la boucle while

  5. #5
    Membre régulier Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 75
    Points
    75
    Par défaut
    Oui effectivement j'avais fini par trouver ^^, mais là je suis face à un autre problème :
    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
      else 
    	{
    	char buf[256];
    	long val[18][3];
    	int i;
    	int j;
    		for(j=0;j<18;j++){
    		while(NULL != fgets(buf, sizeof buf, fid)) 
    		{
    		   printf("%s\n",buf);
    		   char * p = buf;
     
    	           for(i =1; i<4;i++) val[j][i]= strtol(p,&p,10);
    		   printf("%ld %ld %ld\n\n\n",val[j][1],val[j][2],val[j][3]);
    		   }
     
    		}
     
    	}]
    Mon deuxième printf m'affiche correctement la ligne qu'il vient de récupérer, mais si je sort cette ligne de commande de la boucle for(j=0...) et bien là ça ne fonctionne plus, je voudrais savoir pourquoi.

    J'ai mis la boucle for(j=0...) (la boucle du nombre de ligne) en dehors de la boucle while car si il est dedans j'obtiens 18 fois de suite ce genre de chose :
    234 236 245
    0 0 0
    0 0 0
    ...
    jusqu'à la 19ème ligne 0 0 0
    et je me demandais aussi pourquoi il rajoutait une 19ème ligne...

    J'espère que je ne vous embête pas trop avec mes questions peut être un peu stupide ^^

  6. #6
    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
    mais si je sort cette ligne de commande de la boucle for(j=0...) et bien là ça ne fonctionne plus, je voudrais savoir pourquoi.
    Lorsque tu quittes la boucle, j vaut 18 et ton printf est équivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      printf("%ld %ld %ld\n\n\n",val[18][1],val[18][2],val[18][3]);
    et tu es en dehors du tableau val :
    puisque le premier indice ne peut varier qu'entre 0 et 17.

    - Le second indice ne peut varier qu'entre 0 et 2. Ce qui fait que ton code est erronné puisqu'il comporte des val[...][3] :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      for(i =0; i<3;i++) val[j][i]= strtol(p,&p,10);
      printf("%ld %ld %ld\n\n\n",val[j][0],val[j][1],val[j][2]);
    -
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     for(j=0;j<18;j++)
    {
        while(NULL != fgets(buf, sizeof buf, fid)) 
       {
    Cette double boucle est mal fichue. Tu veux arrêter la lecture si tu as EOF ou après 18 lectures (au maximum)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    j = 0 ;
    while(j<18 && NULL != fgets(buf, sizeof buf, fid)) 
    {
      .....
      j++;
    }
    en sortie du while, j indique le nombre de lignes lues.

  7. #7
    Membre régulier Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 75
    Points
    75
    Par défaut
    Merci beaucoup, je crois que j'ai compris ce qui n'allait pas maintenant, c'est vrai que je n'avais pas penser à fusionner la boucle for et la boucle while.
    J'avais compris le principe des indices, d'ailleurs si tu regardes mon code tu remarqueras que j'avais mis comme boucle avec i

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(i =1; i<4;i++) val[j][i]= strtol(p,&p,10);
    C'est pour cela que je pouvais utiliser les indices 1, 2, et 3. C'est une mauvaise habitude de matlab de commencer à 1 et pas à 0, je vais essayer de m'en débarrasser ^^

    Désormais ça fonctionne grâce a tes conseils, mais il me reste une dernière question ^^

    En effet, ça fonctionne bien, mais pas parfaitement, si j'execute ce 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
     else 
    	{
    	char buf[256];
    	long val[18][3];
    	int i;
    	int j;
     
    		while(j<18 && NULL != fgets(buf, sizeof buf, fid)) 
    		{
    		   printf("%s\n",buf);
    		   char * p = buf;
     
    	           for(i =0; i<3;i++) val[j][i]= strtol(p,&p,10);
     
    		   j++;
     
    		}
    	for(j=0;j<18;j++) printf("%ld %ld %ld\n",val[j][0],val[j][1],val[j][2]);
    	}
    mon deuxième printf m'affiche une chose de ce genre :
    225011985 -1075230344 -1208452173
    -1209941118 -1208511070 -1208397836
    1 16 -1208397836
    234 236 245
    241 257 234
    245 235 256
    234 236 245
    241 262 234
    245 235 256
    234 236 245
    241 254 234
    245 235 256
    234 236 245
    241 261 234
    245 235 256
    234 236 245
    241 267 234
    245 235 256
    Les 3 première lignes de mon tableau contiennent donc n'importe quoi est il me manque donc les 9 dernières valeurs. J'ai résolu mon problème en poussant ma boucle jusqu'à 21 et en réinscrivant les valeurs de val à partir de la 4ème ligne dans un autre tableau qui lui fait bien 18*3

  8. #8
    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
    	int j;
     
    		while(j<18 && NULL != fgets(buf, sizeof buf, fid))
    j n'est pas initialisé avant le while et vaut... n'importe quoi

    J'ai résolu mon problème en poussant ma boucle jusqu'à 21 et en réinscrivant les valeurs de val à partir de la 4ème ligne dans un autre tableau qui lui fait bien 18*3
    Très mauvaise idée : On ne résoud pas un problème en le contournant. C'est dangereux. Un comportement anormal signifie un code incorrect. C'est le code qu'il faut corriger, pas le mauvais résultat.

    Dans ton cas, j, non initialisé, devait , par hasard, aujourd'hui, sur cette machine, pour cette exécution,... avoir la valeur 3. Mais ça peut changer "à tout moment" et alors, la "correction" ne marche plus.

  9. #9
    Membre régulier Avatar de Flaherty Mc Coillean
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Décembre 2007
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 108
    Points : 75
    Points
    75
    Par défaut
    Arf désolé j'avais effacé par mégarde mon
    Je suis vraiment stupide, problème résolu, merci beaucoup !

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

Discussions similaires

  1. Export des données à partir d'un fichier texte
    Par Ti-EN dans le forum VBScript
    Réponses: 1
    Dernier message: 07/05/2014, 13h10
  2. [11g] Ouvrir une base des données à partir d'un fichier texte
    Par ajlif dans le forum Oracle
    Réponses: 6
    Dernier message: 25/03/2014, 15h43
  3. chargement des données à partir d'un fichier text
    Par hazem2410 dans le forum Access
    Réponses: 1
    Dernier message: 05/03/2013, 10h02
  4. Réponses: 1
    Dernier message: 21/09/2007, 12h10
  5. extraire des données à partir d'un fichier texte
    Par bigplayer dans le forum Langage
    Réponses: 3
    Dernier message: 03/04/2007, 21h33

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