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 :

Comment lire un fichier en tant que matrice


Sujet :

C

  1. #1
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    388
    Détails du profil
    Informations personnelles :
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 388
    Points : 172
    Points
    172
    Par défaut Comment lire un fichier en tant que matrice
    Bonjour,
    J'ai besoin d'utiliser un fichier .txt nommé "iris-data.txt" pour effectuer des opérations.
    Le souci, c'est que j'ai utilisé la fonction fgets(chaine,....) qui permet de lire le fichier en tant que chaîne, mais finalement, je dois lire le fichier en tant que matrice contenant des vecteurs. Comment changer ça ? Quelle fonction utiliser si ce n'est pas fgets ?
    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
    34
    35
    36
     
    #include <stdlib.h>   
    #include <stdio.h>   
    #include <math.h>	
    #include <string.h>
    #define TAILLE_MAX  4700
     
    int main(int argc, char *argv[])
    {   
        /* Descripteur fichier */
        FILE* fichier = NULL;
     
        /* Ouverture fichier */
        fichier = fopen("iris_data.txt", "r+");
     
        if (fichier != NULL)
        {
     
            // On peut lire et écrire dans le fichier
            printf("Le fichier IRIS DATA est ouvert \n");
     
        char chaine[TAILLE_MAX] = ""; // Chaîne vide de taille TAILLE_MAX
     
        int i=0;
        while(fgets(chaine, TAILLE_MAX, fichier)!= NULL)  // On lit maximum TAILLE_MAX caractères du fichier, on stocke le tout dans "chaine"
        {
         /* Opérations à effectuer */ 	
        }
    else {                                                                               
     
            // On affiche un message d'erreur si on veut
            printf("Impossible d'ouvrir le fichier iris_data.txt");
        }
     
        return 0;
    }
    Merci

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Un fichier est une suite finie d'octet.

    pour lire dedans une matrice, tu as deux approches possibles.
    Soit tu connais la taille exacte de chaque chose qui est dedans (on parle de données positionnelles) et tu peux lire des blocs de char et caster.
    Soit tu as un fichier dit "texte", que tu lis mot par mot, en convertissant chaque mot comme il faut.

    Si c'est ce second cas, tu peux utiliser scanf avec un format bien choisi, en vérifiant la valeur de retour (comme toujours).
    Dans le premier cas, tu peux opter facilement pour fgets, avec la bonne taille, argument par argument.

    Concretement, ce qu'il manque à ton code, c'est une représentation de vecteur et de matrice, et les fonctions capables de les charger depuis ton fichier.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    388
    Détails du profil
    Informations personnelles :
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 388
    Points : 172
    Points
    172
    Par défaut
    Merci pour votre réponse.
    Les données de mon fichier sont sous cette forme :
    5.1,3.5,1.4,0.2,Iris-setosa
    4.9,3.0,1.4,0.2,Iris-setosa
    7.0,3.2,4.7,1.4,Iris-versicolor
    ......................
    Ce que je vais manipuler, ce sera des double, donc 4 colonnes séparées par des virgules (+1 pour garder en mémoire l'étiquette).
    Pour lire ces données j'ai utilisé sscanf pour le formatage, en plus du fgets :
    Exemple

    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
        double nombre1=0.0;
        double nombre2=0.0;
        double nombre3=0.0;
        double nombre4=0.0;	
     
         printf("vecteur numero %d \n",i);
     
        sscanf(chaine, "%lf,%lf,%lf,%lf ", &nombre1, &nombre2, &nombre3, &nombre4);
        printf(" nombre1: %f, nombre2: %f, nombre3: %f, nombre4: %f \n", nombre1, nombre2, nombre3, nombre4);
     
    	/*-----Carré -------*/		
    	double	resultat1 = (nombre1*nombre1);
    	double	resultat2 = (nombre2*nombre2);
    	double	resultat3 = (nombre3*nombre3);
    	double	resultat4 = (nombre4*nombre4);
    	printf("Les resultats sont : %f,%f,%f,%f \n", resultat1, resultat2, resultat3, resultat4);
    Je ne comprends pas comment manipuler des vecteurs à la place.
    En faisant ceci, ça ne s'exécute pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    for (int i=0;i<=4;i++)	
    {
        printf("vecteur numero %d \n",i);
     
     
        char * vecteur;
     
        sscanf(chaine, "%lf, ", &vecteur[i]);
        printf(" vecteur : %f, \n", vecteur[i]);
     }

  4. #4
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    L'idée est dans ton premier morceau de code : remplace simplement tes quatres variables indépendantes par un tableau.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        double v[4] = { 0., 0., 0., 0. };
        sscanf(chaine, "%lf,%lf,%lf,%lf ", &v[0], &v[1], &v[2], &v[3]);
    Penses à la gestion d'erreur.

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    il faut un type dédié, que ce soit un simple float[4], un double[4] (ce qui est mieux, du fait de la précision), ou une structure, que je te recommande.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations forums :
    Inscription : Juillet 2012
    Messages : 200
    Points : 342
    Points
    342
    Par défaut
    Bonsoir.
    Deux petites remarques :
    - Comme l'a dit leternel, ce serait bien d'utiliser une struct pour représenter un vecteur.
    - Il n'est pas nécessaire d'utiliser fgets pour lire une ligne dans le fichier et ensuite scanner la chaîne récuperée. Les données peuvent êtres lues directement dans le fichier.
    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
    34
    35
    36
    37
    38
    #include <stdio.h>
     
    // Astuce pour pouvoir définir une taille max pour l'étiquette avec 'printf'
    // Chercher 'Stringification' sur Google (en anglais) pour plus d'infos
    #define XSTR(a) STR(a)
    #define STR(a)  #a
     
    // Pour des étiquettes de longueur 20 au plus (à adapter à vos besoins)
    #define LONGUEUR_MAX_ETIQUETTE 20
     
    struct vecteur {
        double coords[4];
        char etiquette[LONGUEUR_MAX_ETIQUETTE + 1];
    };
     
    int main()
    {
        struct vecteur v;
        FILE *f;
        int n; // Représente le nombre de lignes lues depuis le fichier
     
        f = fopen(...);
        if(f == NULL)
            return;
     
        n = 0;
        while( scanf("%lf%*c%lf%*c%lf%*c%lf%*c%" XSTR(LONGUEUR_MAX_ETIQUETTE) "s",
                      &v.coords[0], &v.coords[1], &v.coords[2], &v.coords[3], v.etiquette) > 0) {
            n++;
            // Faire ici le traitement sur le vecteur numero n
            // ....
        }
       // Ici n contiendra le nombre de lignes lues. A toutes fins utiles...
     
       fclose(f);
     
       return 0;
    }
    Petite explication :
    - %*c permet de gérer le problème des données separées par des virgules.
    - scanf renvoie le nombre de variables éffectivement écrites, ce qui est ici utilisé pour détecter la fin du fichier
    PS : Si vous devez travailler sur l'ensemble des vecteurs et non individuellement, il suffit de déclarer un tableau de vecteurs. Mais dans ce cas, il faudra savoir combien de lignes au maximum il y aura dans le fichier pour utile pour réserver de la place.

  7. #7
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Concis, mais son fichier a intérêt à être béton.

    Quelques soucis avec le programme ci-dessus :
    • %d représente un entier écrit sous forme décimale, avec une entrée comme celle proposée le comportement est indéfini ;
    • la valeur de retour de scanf n'est pas stockée : une ligne mal formée (ou simplement une étiquette non présente) n'est pas prise en charge ;
    • si l'un des nombres n'est pas représentable par le type de destination, le comportement est indéfini.

  8. #8
    Membre averti
    Homme Profil pro
    Inscrit en
    Juillet 2012
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Bénin

    Informations forums :
    Inscription : Juillet 2012
    Messages : 200
    Points : 342
    Points
    342
    Par défaut
    @Matt_Houston : vous avez raison. J'ai modifié le méssage original (bourré d'erreurs). J'ai honte de moi

Discussions similaires

  1. Réponses: 6
    Dernier message: 19/04/2013, 14h16
  2. [BCB 5]Comment lire un fichier AVI avec un TAnimate ?
    Par Sitting Bull dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/09/2004, 11h57
  3. Comment lire un fichier DB en cours d'utilisation par 1 autr
    Par jbat dans le forum Bases de données
    Réponses: 4
    Dernier message: 12/03/2004, 11h06
  4. Comment lire un fichier image
    Par Charlemagne dans le forum DirectX
    Réponses: 9
    Dernier message: 12/03/2004, 00h22

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