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 :

[débutant]entrée d'une matrice tabulée (txt) dans un tableau


Sujet :

C

  1. #1
    Membre confirmé Avatar de Ickou
    Inscrit en
    Avril 2005
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 174
    Par défaut [débutant]entrée d'une matrice tabulée (txt) dans un tableau
    Salut à tous

    J'ai un fichier texte dont le séparateur est la tabulation et il contient une matrice de nombres flottants.....
    Je voudrais récupérer la matrice dans un tableau pour faire des calculs.
    J'ai récupéré le code de gege2061 pour couper une chaine.

    J'ai plusieurs problèmes :
    - n'étant pas doué , je n'arrive pas à utiliser le "str_split"
    - je sais pas comment je vais pouvoir récupérer les données en float car pour l'instant c'est du char.....

    Quelqu'un pourrait-il me corriger le code : :

    Voici ce que j'ai tenté pour l'instant :
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    // 1er argument --> nom du fichier
    // 2ème argument --> nombre de lignes
    // 3ème argument --> nombre de colonnes
    // 4ème argument --> taille maxi d'une ligne
     
    int main(int argc, char *argv[]){
      //Déclaration des variables
      int nb_ligne=atoi(argv[2]);
      int nb_colonne=atoi(argv[3]);
      int maxiligne=atoi(argv[4]);
      int i;
      char *split;
      float **tab;
      FILE* entree;
      char *ligne;
      int line=0;
      int columm=0;
      char *p;
      char *sep ="\t";
      char tab2[20];
      //Allocation de la taille maxi d'une ligne
      ligne = (char*) malloc ( sizeof(char)  *  maxiligne);
      //Allocation de la matrice
     
      /* Allocation de la 1er dimension */
      tab = malloc ( sizeof(*tab)  *  nb_ligne);
      /* Allocation des tableaux */
      for (i=0; i<nb_ligne; i++)
      {
        tab[i] = malloc ( sizeof(**tab) * nb_colonne);
      }
     
      //Ouverture du fichier de données
      if((entree= fopen(argv[1], "r")) == NULL)   {
        return EXIT_FAILURE;
      }
      //tant qu'il y a une ligne
      while(fgets(ligne, sizeof ligne, entree)){
        columm=0;
        //On vire les retour chariot
        p = strchr (ligne, '\n');
        if (p)
        {
         *p = 0;
        }
     
        //on split et on remplit le tableau (tab)
        printf ("%s",ligne);
        *tab[line] = str_split (*ligne,*sep);
        for(i=0;i<5;i++)
        {
          printf("%s",tab2[i]);
        }
        //split = strtok(ligne, sep);
        //while ( split != NULL ) {
          //tab[line][columm]=(float)split;
          //printf("token: %10s\n", split);
         // split = strtok(NULL, sep);
         // columm++;
        //}
        //on incremente la ligne pour le tableau
        line++;
      }
     
     
      return 0;
    }
     
     
    //LE SPLIT DE PERL
    char **str_split (char *s, const char *ct)
    {
       char **tab = NULL;
     
       if (s && ct)
       {
          int i;
          char *cs = NULL;
          size_t size = 1;
     
    /* (1) */
          for (i = 0; (cs = strtok (s, ct)); i++)
          {
             if (size <= i + 1)
             {
                void *tmp = NULL;
     
    /* (2) */
                size <<= 1;
                tmp = realloc (tab, sizeof (*tab) * size);
                if (tmp)
                {
                   tab = tmp;
                }
                else
                {
                   fprintf (stderr, "Memoire insuffisante\n");
                   free (tab);
                   tab = NULL;
                   exit (EXIT_FAILURE);
                }
             }
    /* (3) */
             tab[i] = cs;
             s = NULL;
          }
          tab[i] = NULL;
       }
       return tab;
    }

  2. #2
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Faudrait-il déjà que le code compile...

    Une bonne chose serait de mettre la fonction str_split au dessus du main... Ensuite je te laisse corriger les autres erreurs. C'est le meilleur des exercices...

    Ensuite on parlera du code...

    code.c: In function 'main':
    code.c:53: warning: implicit declaration of function 'str_split'
    code.c:56: warning: format '%s' expects type 'char *', but argument 2 has type 'int'
    code.c:16: warning: unused variable 'split'
    code.c: At top level:
    code.c:10: warning: unused parameter 'argc'
    code.c:76: error: conflicting types for 'str_split'
    code.c:53: error: previous implicit declaration of 'str_split' was here
    code.c: In function 'str_split':
    code.c:88: warning: comparison between signed and unsigned
    Jc

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut Re: [débutant]entrée d'une matrice tabulée (txt) dans un tab
    Citation Envoyé par Ickou
    Voici ce que j'ai tenté pour l'instant :
    Beaucoup trop compliqué. Il faut étudier la fonction strtod() qui est faite pour ce genre de récupération...

    Par contre, il manque la gestion des erreurs et la libération de la mémoire. Il n'y a aucun contrôle de la validité des paramètres...

    Travailler en double. C'est plus précis.
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    static void usage(void)
    {
       puts(
          "1er argument --> nom du fichier\n"
          "2ème argument --> nombre de lignes\n"
          "3ème argument --> nombre de colonnes\n"
          "4ème argument --> taille maxi d'une ligne\n"
       );
    }
     
    int main(int argc, char *argv[])
    {
       if (argc > 4)
       {
          //Ouverture du fichier de données
          FILE *entree = fopen(argv[1], "r");
          if (entree != NULL)
          {
             size_t nb_ligne = (size_t)atoi(argv[2]);
             size_t nb_colonne = (size_t)atoi(argv[3]);
             size_t maxiligne = (size_t)atoi(argv[4]);
             //Allocation de la matrice
             /* Allocation de la 1er dimension */
             double **tab = malloc (sizeof * tab * nb_ligne);
             if (tab != NULL)
             {
                int err = 0;
                /* Allocation des tableaux */
                {
                   size_t i;
                   for (i = 0; i < nb_ligne; i++)
                   {
                      tab[i] = malloc ( sizeof * tab[i] * nb_colonne);
     
                      if (tab[i] == NULL)
                      {
                         err = 1;
                      }
                   }
                   if (err)
                   {
                      for (i = 0; i < nb_ligne; i++)
                      {
                         free (tab[i]), tab[i] = NULL;
                      }
                   }
                }
                if (!err)
                {
                   //Allocation de la taille maxi d'une ligne
                   char *ligne = malloc (maxiligne);
                   if (ligne != NULL)
                   {
                      size_t lin = 0;
                      //tant qu'il y a une ligne
                      while (fgets(ligne, maxiligne, entree) != NULL && !err)
                      {
                         //On vire les retour chariot
                         {
                            char *p = strchr (ligne, '\n');
                            if (p != NULL)
                            {
                               *p = 0;
                            }
                            else
                            {
                               /* clean */
                               int c;
                               while ((c = fgetc(entree)) != '\n' && c != EOF)
                               {
                               }
                            }
                         }
                         printf ("'%s'\n", ligne);
                         /* recuperer les donnes et les stocker dans le tableau. */
                         {
                            char *pend = ligne;
                            size_t col = 0;
                            while (*pend)
                            {
                               if (col < nb_colonne)
                               {
                                  tab[lin][col] = strtod(pend, &pend);
                                  col++;
                               }
                               else
                               {
                                  printf ("trop de colonnes\n");
                                  err = 1;
                                  break;
                               }
                            }
                         }
                         if (lin < nb_ligne)
                         {
                            lin++;
                         }
                         else
                         {
                            printf ("trop de lignes\n");
                            err = 1;
                         }
                      }
                      free (ligne), ligne = NULL;
                   }
                   {
                      size_t i;
                      /* display */
                      for (i = 0; i < nb_ligne; i++)
                      {
                         size_t j;
                         for (j = 0; j < nb_colonne; j++)
                         {
                            printf ("%8.2f", tab[i][j]);
                         }
                         printf ("\n");
                      }
                      /* free */
                      for (i = 0; i < nb_ligne; i++)
                      {
                         free (tab[i]), tab[i] = NULL;
                      }
                   }
                }
                free(tab), tab = NULL;
             }
          }
          else
          {
             perror(argv[1]);
          }
       }
       else
       {
          usage();
       }
       return 0;
    }
    Avec ce fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    12.34 56.78 23.45
    45.67 89.01 34.56
    j'obtiens ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    '12.34 56.78 23.45'
    '45.67 89.01 34.56'
       12.34   56.78   23.45
       45.67   89.01   34.56
    Press ENTER to continue.
    Nota : On pourrait supprimmer les trois derniers paramètres en faisant une analyse du fichier avant le chargement, ou avec des méthodes 'souples' (avancé)

  4. #4
    Membre confirmé Avatar de Ickou
    Inscrit en
    Avril 2005
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 174
    Par défaut
    merci pou cette aide précieuse

  5. #5
    Membre confirmé Avatar de Ickou
    Inscrit en
    Avril 2005
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 174
    Par défaut
    j'ai une dernière petite question concernant le cas où il n'y est pas de valeur entre deux tabulations.... (mon tableau.txt tabulé contient aussi des vides et des 0)

    Je pense faire ça mais il y a peut-être mieux : : : :

    Lors de la création du tableau.txt, remplacer les vides par 666.66 par exemple puis lors de mes calculs en utilisant une boucle if(tab[truc][truc2]!='666.66'){}, je pourrais ignorer ces cases.......

  6. #6
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par Ickou
    j'ai une dernière petite question concernant le cas où il n'y est pas de valeur entre deux tabulations.... (mon tableau.txt tabulé contient aussi des vides et des 0)

    Je pense faire ça mais il y a peut-être mieux : : : :

    Lors de la création du tableau.txt, remplacer les vides par 666.66 par exemple puis lors de mes calculs en utilisant une boucle if(tab[truc][truc2]!='666.66'){}, je pourrais ignorer ces cases.......
    On ne fait jamais de test == ou != avec des nombres flottants mais on utilise un epsilon pour voir si on est proche ou non...

    Mais c'est généralement une mauvaise idée puisque le jour ou tu auras un 666.66 dans ton tableau, tu vas l'ignorer...

    Jc

  7. #7
    Membre confirmé Avatar de Ickou
    Inscrit en
    Avril 2005
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 174
    Par défaut
    merci pour cette précision

    donc je dois utiliser un chiffre que je n'ai aucune chance de renconter dans mes calculs (un chiffre bien plus grand par exemple, comme 1000000) et faire la comparaison avec ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include <cmath> // pour std::abs
    #include <limits> // pour std::numeric_limits
     
    int vide = 1000000;
     
    if (std::abs(tab[truc][truc2] - vide) > std::numeric_limits<float>::epsilon())
    {
        // Ok
    }

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Ickou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #include <cmath> // pour std::abs
    Pas du C...

  9. #9
    Membre confirmé Avatar de Ickou
    Inscrit en
    Avril 2005
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 174
    Par défaut
    Il faut écrire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #define EPSILON 0.01
    int vide = 1000000; 
     
    if (tab[truc][truc2] > vide - EPSILON && tab[truc][truc2] < vide + EPSILON)
    {}

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Ickou
    Il faut écrire ça :
    Ou plutôt ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include <float.h>
     
    #define EPSILON DBL_EPSILON
    int vide = 1000000; 
     
    if (tab[truc][truc2] > vide - EPSILON && tab[truc][truc2] < vide + EPSILON)
    {}

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 29/06/2007, 14h49
  2. Réponses: 4
    Dernier message: 21/06/2007, 01h11
  3. [Débutant] Création d'une matrice de confusion
    Par Alucard9800XT dans le forum MATLAB
    Réponses: 4
    Dernier message: 15/05/2007, 09h19
  4. [Débutant] Transformation d'une matrice 3D en une matrice 1D
    Par Alucard9800XT dans le forum MATLAB
    Réponses: 7
    Dernier message: 10/05/2007, 15h07
  5. [Débutant] Remplissage d'une matrice
    Par Keldou dans le forum Octave
    Réponses: 2
    Dernier message: 24/04/2007, 19h54

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