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

SL & STL C++ Discussion :

Pb fonction strtok pour parser


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Par défaut Pb fonction strtok pour parser
    Bonjour,

    J'essaye de parser un fichier csv avec la fonction strtok cela fonctionne plutot bien. Seulement quand j'essaye de stocker les données dans une matrice mes données sont erronées ?

    Voici mon fichier CSV :
    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
    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
    int main(int argc, _TCHAR* argv[])
    {
    FILE *myfile;
    char line1[1000];
    char line2[1000];
    char *stptr;
    int lcount = 0; // Nombre de cellule
    double**data; // tableau de stockage
    int i,j;
    double n=0;
    double nb_colonnes=2;
    double duree_historique=10;
     
    //Allocation table data
    	data=(double**)malloc(duree_historique*sizeof(double*));
    		for (j = 0;j<duree_historique;j++)
                   {
    			data[j]=(double*)malloc(nb_colonnes*sizeof(double));
    		}
    	// Initialisation
    	 for(i=0;i<duree_historique;i++){
                       for (j = 0;j<nb_colonnes;j++)
                      {
    			data[i][j] = 0;
    		  }
    	 }
     
    	while (fgets(line1,sizeof line1,myfile) != NULL){ // parcours le fichier
    		lcount = 0;
    		strcpy(line2,line1);
    		stptr = strtok (line2,";");
    		j=0;
    		while (stptr != NULL){
    			  cout<<"\ni = "<<i;
    			  cout<<" j = "<<j<<"\n";
    			  printf ("%s ",stptr);
    			  stptr = strtok (NULL, ";");
    			  n=atof(line2);
    			  data[i][j]=n;
    			  j++;
    		}
    		i++;
    		j--;
    	}
     
    		fclose(myfile);
    		//Affichage du tableau de stockage
    		for(i=0;i<10;i++){
    			for(j=0;j<2;j++){
    				cout<<data[i][j]<<" ";
    			}
    			cout<<"\n";	
    		}
    		getch();
    	return 0;
    }


    La sortie console avec le strtok me donne bien les bonnes valeurs.
    Mais lorsque j'affiche ma matrice j'obtiens :



    Une idée ?

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Par défaut
    Arg que c'est moche ce mélange de C et de C++...
    On dispose en C++ de fonctions plus puissantes que le strok du C... mais veux-tu faire du C++ ou veux-tu faire du C mais dans ce cas-là tu n'est pas sur le bon forum.

  3. #3
    Membre habitué
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Par défaut
    Oui ce n'est peut etre pas tres propre ...
    Je t'avoue peut importe que ca soit en c ou C++
    Dois je plutot poster sur l'autre forum alors ?

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Par défaut
    Si tu veux faire du C, poste sur l'autre forum.

    Je te donne ici l'équivalent en C++ de ton code.
    On peut améliorer en utilisant une matrice unidimensionnelle.

    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
     
    #include <fstream>
    #include <iostream>
    #include <sstream>
     
    using namespace std;
     
    int main(int argc, char** argv[]) {
     
      double **data; // tableau de stockage
      int nb_colonnes=2;
      int duree_historique=10;
     
      //Allocation table data
      data = new double* [duree_historique];
      for (int j = 0 ; j < duree_historique ; j++) {
        data[j] = new double [nb_colonnes];
      }
     
      // Initialisation
      for(int i=0 ; i < duree_historique ; i++) {
        for (int j = 0 ; j < nb_colonnes ; j++) {
          data[i][j] = 0;
        }
      }
     
      ifstream myfile ("file.csv");
     
      if (myfile) {
     
        int count = 0;
        string line;
     
        while (getline (myfile, line)) {
          double d1, d2;
          char sep;
          istringstream iss (line);
          iss >> d1 >> sep >> d2;
          if (iss.fail () || sep != ';') {
    	cerr << "Erreur à la ligne " << ++count << endl;
          } else {
    	data[count][0] = d1;
    	data[count][1] = d2;
    	count++;
          }
        }
     
        myfile.close ();
     
      } else {
        cerr << "Ne peut pas ouvrir le fichier" << endl;
      }
     
      //Affichage du tableau de stockage
      for(int i = 0 ; i < 10 ; i++) {
        for(int j = 0 ; j < 2 ; j++) {
          cout<<data[i][j]<<" ";
        }
        cout<<"\n";	
      }
     
      return 0;
     
    }

  5. #5
    Membre habitué
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Par défaut
    Merci pour ta réponse, effectivement c'est nettement plus propre !

    Juste une question à quoi sert ton test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (myfile.fail ()) {
          cerr << "Erreur à la ligne " << count + 1 << endl;
    }
    J'ai l'erreur des que je suis à ligne 4 en supposant que j'ai 3 lignes de données dans mon csv.

  6. #6
    Membre habitué
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Par défaut
    Mille excuses, effectivement c'était le probleme de la ligne vide. J'ai parlé trop vite.

    J'ai un autre petit souci, les données du csv proviennent d'excel et certaines valeurs peuvent etre à virgules
    ex: 2;10,3

    Ca pose probleme avec le C++ qui voudrait plutot : 2;10.3

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Par défaut
    Citation Envoyé par filipbou Voir le message
    Merci pour ta réponse, effectivement c'est nettement plus propre !

    Juste une question à quoi sert ton test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (myfile.fail ()) {
          cerr << "Erreur à la ligne " << count + 1 << endl;
    }
    J'ai l'erreur des que je suis à ligne 4 en supposant que j'ai 3 lignes de données dans mon csv.
    J'ai corrigé le code. Cf. mon post précédent.
    La ligne devient donc iss.fail() et non plus myfile.fail().
    Je vérifie juste que la ligne est bien formatée suivant double;double.
    Oui, il y a une erreur à la ligne 4. Améliore le code pour qu'une ligne vide ne provoque pas une erreur.

  8. #8
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Voilà le code après correction:

    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
    #include <cstdio>
    #include <cstdlib>
    #include <conio.h>
    #include <iostream>
     
    using namespace std;
     
    int main(int argc, char* argv[])
    {
        FILE *myfile=fopen("text.txt", "r");
        char line1[1000];
        char line2[1000];
        char *stptr;
        int lcount = 0; // Nombre de cellule
        double**data; // tableau de stockage
        int i,j;
        double n=0;
        double nb_colonnes=2;
        double duree_historique=10;
     
      //Allocation table data
        data=(double**)malloc((int)(duree_historique)*sizeof(double*));
        for (j = 0;j<duree_historique;j++)
        {
            data[j]=(double*)malloc((int)(nb_colonnes)*sizeof(double));
        }
        // Initialisation
        for (i=0;i<duree_historique;i++){
            for (j = 0;j<nb_colonnes;j++)
            {
                data[i][j] = 0;
            }
        }
        i=0;
        while (fgets(line1,sizeof line1,myfile) != NULL){ // parcours le fichier
            lcount = 0;
            strcpy(line2,line1);
            stptr = strtok (line2,";");
            j=0;
            while (stptr != NULL){
                cout<<"\ni = "<<i;
                cout<<" j = "<<j<< endl;
                printf ("%s \n",stptr);
                n=atof(stptr);
                stptr = strtok (NULL, ";");
                data[i][j]=n;
                j++;
            }
            i++;
            j--;
        }
     
        fclose(myfile);
        //Affichage du tableau de stockage
        for (i=0;i<10;i++){
            for (j=0;j<2;j++){
                cout<<data[i][j]<<" ";
            }
            cout<<endl;
        }
        getch();
        return 0;
    }
    D'abord j'ai mis des (int) dans le malloc sinon le compilo était pas d'accord.
    Ensuite, j'ai rajouté un "i=0" avant le while sinon j'avait une segfault
    Sinon, j'ai remplacé les cout << "n" par des cout << endl.
    Sinon, tu utlises <iostream> ou <iostream.h>?

    Enfin, pour ton problème:
    Tu mets le strcpy avant ta deuxième boucle!!
    Ce qui veut dire que line2 n'est pas changée dans ta boucle, c'est pour ça que tu as deux fois les mêmes chiffres.

    Enfin c'est corrigé

    Edit: grillé...
    Je te conseille le code plus orienté C++ posté plus haut.

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

Discussions similaires

  1. fonction pour parser /proc/[pid]/stat
    Par dodo285 dans le forum Linux
    Réponses: 2
    Dernier message: 05/09/2013, 17h43
  2. [PHP 5.2] Quelles fonctions pour parser du HTML ET modifier le contenu?
    Par Nixar dans le forum Langage
    Réponses: 30
    Dernier message: 09/05/2012, 15h31
  3. fonction pour parser un fichier
    Par Dirty Harry dans le forum Langage
    Réponses: 7
    Dernier message: 30/01/2007, 05h13
  4. Fonction/méthode pour obtenir l'IP de la machine
    Par sirex007 dans le forum Web & réseau
    Réponses: 3
    Dernier message: 10/04/2003, 14h36
  5. Réponses: 3
    Dernier message: 02/09/2002, 18h49

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