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 fichier .csv MFC


Sujet :

C++

  1. #21
    Invité
    Invité(e)
    Par défaut
    Merci, j'ignorais cette finesse.
    Moi, j'aurais écrit
    A1;B1;C1
    A2;B\\n2;C2
    ou
    A1;B1;C1
    A2;"B\n2";C2
    ou même
    A1;B1;C1
    A2;"B\\n2";C2
    Mais cela est-il bien dans l'esprit d'un CSV?

  2. #22
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    De manière générale, tu ne pourra pas utiliser une formule simple pour déterminer l'offset du fichier auquel tu dois aller pour lire la Nième donnée.

    La raison est simple: le nombre de caractères qui composent l'ensemble des informations relatives à une donnée varie beaucoup trop:
    utilise 11 caractères
    en utilise déjà 13... Et je ne parle pas de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    0;A16;GEN_0;Type carter;x
    qui en utilise 25 ni de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    28;D16;GEN_28;Dernière OP travaillée;x
    pour lequel je renonce à compter

    De plus, il faut se rappeler que les temps d'accès à un fichier sont particulièrement grand comparer aux temps d'accès à la mémoire.

    Il y a donc très largement intérêt à lire l'ensemble du fichier en une fois de manière à créer une collection (un tableau) de données permettant de représenter les différentes informations contenues dans le fichier.

    Cela pourrait se baser sur une structure proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct Data
    {
        int octet;
        std::string type;
        std::string variable;
        std::string affichage;
        bool archive;
    };
    (ou l'équivalent MFC).

    Tu commencerais, au lancement de l'application, par lire ton fichier, ligne par ligne, et par remplir un tableau de Data dont les différents champs seraient définis sur base de ce que tu lis dans le fichier.

    Tout le reste du travail s'effectuerait sur base de se tableau.

    Il ne faudra pas oublier de sauvegarder les données au plus tard juste avant de quitter l'application si elle y a apporté des modifications / ajouts
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #23
    Membre averti
    Inscrit en
    Juillet 2010
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 16
    Par défaut
    Bonjour,
    alors j'ai essayé pas mal de truc. Je pense que le plus important à l'heure actuelle, c'est que je réussie à detecter une chaine de caractère, par exemple trouver la colonne "variable". Est ce que je peux jouer avec le numéro de colonne, puisque la colonne variable est toujours au même endroit. Ensuite rechercher dans toute cette colonne les "GEN_XX" puis recuperer les données associées.
    Cependant je ne voit donc pas comment dire "va chercher toujours les données de la colonne 3". Et comment incrementer mon string "GEN_XX" ?

  4. #24
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    J'ai l'impression que tu ne prends pas la bonne approche. Relis bien le message de Koala.

    L'idée, c'est que tu lises tout ton fichier, et qu'au fur et à mesure de la lecture, tu remplisses un std::vector de ta structure Data. Pour chaque enregistrement, tu peux récupérer facilement les valeur de la colonne 0, 1, 2, etc, et les associer à la valeur correspondante de la structure data.

    Ensuite, tu pourras parcourir ce vector pour retourner, par exemple, un nouveau std::vector, de std::string cette fois-ci, contenant toute la liste des données de la colonne 3.

  5. #25
    Membre averti
    Inscrit en
    Juillet 2010
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 16
    Par défaut
    Me revoilà,
    alors, j'ai pas mal cherché, et j'ai trouvé l'equivalent d'une fonction split pour MFC. Cette fonction est censée me retourner un tableau dans lequel sont inscrits tous les champs lus, ça m'aidera surement a bien me retrouver par la suite. Mais sans resultats pour le moment. Si vous avec une petite idée.

    La fonction principale
    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
     
    FILE * fichierCsv;			// Nom du fichier qu'on va utiliser
    	char * cToken;	       // Buffer du contenu des valeurs d'une ligne
    	char * cToken2;	      // Buffer du contenu des valeurs d'une ligne
    	char cBuffligne[1500] = "";	// Buffer du contenu de la ligne du fichier
    	CString ligne;
    	int iCompteur = 0;	// Compte le nombre de fois où on boucle
    	int colonneProprietaire;
    	CString delimiter = _T(";");
    	CStringArray result;
     
    	if(( fichierCsv = fopen ("mapping.csv","r")) != NULL)//Si pas de problème lors de l'ouverture du fichier														
    	{
     
    		while(fgets(cBuffligne,sizeof(cBuffligne),fichierCsv)!= NULL)//pour toute les lignes du fichier ou jusqu'a ce que "d" soit faux
    		{
    			ligne = _T("");
    			for(int i = 0 ; i<sizeof(cBuffligne); i++)
    			{
    				ligne += cBuffligne[i];
    			}
     
    			SplitString(ligne,delimiter,result);
                    }
    La fonction split
    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
    int CCsvDlg::SplitString(const CString& input, 
      const CString& delimiter, CStringArray& results)
    {
      int iPos = 0;
      int newPos = -1;
      int sizeS2 = delimiter.GetLength();
      int isize = input.GetLength();
     
      CArray<INT, int> positions;
     
      newPos = input.Find (delimiter, 0);
     
      if( newPos < 0 ) { return 0; }
     
      int numFound = 0;
     
      while( newPos > iPos )
      {
        numFound++;
        positions.Add(newPos);
        iPos = newPos;
        newPos = input.Find (delimiter, iPos+sizeS2+1);
      }
     
      for( int i=0; i <= positions.GetSize(); i++ )
      {
        CString s;
        if( i == 0 )
          s = input.Mid( i, positions[i] );
        else
        {
          int offset = positions[i-1] + sizeS2;
          if( offset < isize )
          {
            if( i == positions.GetSize() )
              s = input.Mid(offset);
            else if( i > 0 )
              s = input.Mid( positions[i-1] + sizeS2, 
                     positions[i] - positions[i-1] - sizeS2 );
          }
        }
        if( s.GetLength() > 0 )
          results.Add(s);
      }
      return numFound;
    }

  6. #26
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Le problème n'est pas dans le code, il est avant tout algorithmique. Il faut d'abord trouver l'algorithme qui répond à ton problème, sinon se lancer dans l'écriture d'un code approximatif ne servira pas à grand chose.

    Ici tu as plusieurs étapes, qui peuvent être fait en parallèle ou pas :
    - lire le contenu du fichier
    - identifier chaque ligne du fichier
    - splitter chaque ligne selon le caractère ';'
    - remplir une structure en mémoire correspondant au contenu de ton fichier

    Dans le code que tu montres, il manque la dernière étape. Cela dit, je pense que tu as les éléments pour les faire.

  7. #27
    Membre averti
    Inscrit en
    Juillet 2010
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 16
    Par défaut
    C'est ce que je fais, j'ouvre mon fichier, je recupere la ligne, je split, et j'envoie vers une structure (enfin j'essaie, j'ai declaré ma structure, mais quand je fais mapping.variable, il crash)

  8. #28
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Désolé mais si tu ne postes pas le code qui plante, ça va être difficile de t'aider.

    Dans le code que tu as posté, je ne vois ni la structure, ni le code qui ajoute des choses dedans...

  9. #29
    Membre averti
    Inscrit en
    Juillet 2010
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 16
    Par défaut
    Désolé, j'ai avancé, donc ça remplit pas ma structure. mon result[0] à toujours la même valeur, malgrès que je change de ligne


    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
    void CCsvDlg::OuvrirCsv()
    {
     
    	FILE * fichierCsv;									// Nom du fichier qu'on va utiliser
    	char cBuffligne[150] = "";							// Buffer du contenu de la ligne du fichier
    	CString ligne;
    	CString delimiter = _T(";");
    	CStringArray result;
    	CString tab = _T("");
     
    	if(( fichierCsv = fopen ("mapping.csv","r")) != NULL)//Si pas de problème lors de l'ouverture du fichier														
    	{
    		MAPPING mapping;
    		//if (fgets(cBuffligne,sizeof(cBuffligne),fichierCsv) != NULL)	
    		while(fgets(cBuffligne,sizeof(cBuffligne),fichierCsv)!= NULL)//pour toute les lignes du fichier ou jusqu'a ce que "d" soit faux
    		{
     
     
    			ligne = CString(cBuffligne);
    			SplitString(ligne,delimiter,result);
     
    			mapping.variable = result[0]
     
    		}
    	}fclose(fichierCsv);
    }

    et ma structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct 
    {
    	CString variable;
    	CString activer;
    	int octet;
    	CString affichage;
    	CString type; 
    }MAPPING;
    Edit : probleme resolu, le CString results est alloué à chaque changements de ligne

  10. #30
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    CStdioFile en MFC non ? Avec CStdioFile::ReadString ça t'évitera d'horribles lignes du genre char cBuffligne[150] = "";
    Et si tu restes 100% MFC, il me semble me souvenir d'un CArray qui pourrait faire l'affaire pour stocker tes lignes.
    A la volée (car je n'ai pas de MFC sous la main), ce devrait être quelque chose comme ça :
    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
    void CCsvDlg::OuvrirCsv()
    {
    	CStdioFile fichier;
    	CString ligne;
    	CString delimiter = _T(";");
    	CStringArray result;
    	CArray<MAPPING> tableau_resultat;
     
    	if(( fichier.Open(_T("mapping.csv"),CFile::modeWrite)))//Si pas de problème lors de l'ouverture du fichier														
    	{
    		MAPPING mapping;
    		while(fichier.ReadString(ligne))//pour toute les lignes du fichier ou jusqu'a ce que "d" soit faux
    		{
    			SplitString(ligne,delimiter,result);
     
    			mapping.variable = result[0];
    			tableau_resultat.Add (mapping);
     
    		}
    	}
    }

Discussions similaires

  1. Lire fichier CSV et créer images
    Par jcaspar dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 0
    Dernier message: 14/04/2010, 17h31
  2. lire fichier csv
    Par oudghouti dans le forum VB.NET
    Réponses: 12
    Dernier message: 20/01/2010, 15h40
  3. Lire fichier CSV avec tabulation comme séparation
    Par theNoob dans le forum Langage
    Réponses: 3
    Dernier message: 07/09/2009, 18h52
  4. lire fichier csv
    Par nico0812 dans le forum C#
    Réponses: 4
    Dernier message: 17/04/2007, 18h40
  5. lire fichier csv et en extraire des infos
    Par isaglada dans le forum VBScript
    Réponses: 2
    Dernier message: 12/02/2007, 13h04

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