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 un fichier CSV et sauvegarder son contenu dans un tableau en C


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 3
    Par défaut Lire un fichier CSV et sauvegarder son contenu dans un tableau en C
    Bonjour à tous

    Voilà, je recherche un peu d'aide sur un problème qui pour vous sera sûrement très simple !

    Je dispose d'un fichier CSV (comma-separated values) nommé nombres.csv contenant des nombres de la forme suivante :

    (ceci est un exemple)

    15322,000,17800,000
    15325,000,17800,000
    15327,000,17800,000
    etc ...

    Je cherche à sauvegarder dans un tableau de type flot (que je nommerai tableau) à une dimension les nombres suivants :
    tableau[0]=15322,000
    tableau[1]=15325,000
    tableau[2]=15327,000

    c'est à dire seulement la première colonne.

    Je voudrai (après je ne sais pas si c'est le moyen le plus adapté) procéder à peu près de cette façon :

    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
    #include <stdio.h>
     
    int main(int argc, const char * argv[])
    {
        FILE* fichier = NULL;
        int i =0;
     
        float tableau[200]={0};
     
        fichier = fopen("nombres.csv", "r");
     
        if (fichier != NULL)
        {
           for(i = 0; i < 200; i++)
           {
           fscanf(fichier, "%f ", &tableau[i]);
           }
            fclose(fichier);
        }
     
        return 0;
     
    }

    J'ai quelques difficultés à gérer la séparation des nombres par les virgules : c'est à dire, comment lui dire de prendre le nombre de la ligne d'en dessous juste après avoir rencontré une virgule ?

    Si vous pouviez m'aider, je vous en serai reconnaissant.

    En vous souhaitant une bonne journée

  2. #2
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Citation Envoyé par Maxxie12 Voir le message
    Bonjour à tous
    J'ai quelques difficultés à gérer la séparation des nombres par les virgules : c'est à dire, comment lui dire de prendre le nombre de la ligne d'en dessous juste après avoir rencontré une virgule ?
    J'ai pas compris ce que tu voulais dire, à mon avis, soit tu lis tout le fichier d'un coup, soit ligne par ligne.

    Ensuite, soit tu écris ta propre grammaire pour parser un fichier CSV, soit tu utilises une lib éxistante qui fait ça déjà très bien (j'ai mis les premiers trucs trouvés sur le net, à vérifier donc):

    http://sourceforge.net/projects/libcsv/
    http://cm.bell-labs.com/cm/cs/tpop/code.html

    Personnellement, je te conseille d'utiliser une lib, tu gagneras du temps, sauf si tu as vraiment envie de réinventer la roue.

  3. #3
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,

    Tu ne peux pas utiliser le même séparateur (ici la virgule) pour séparer à la fois les nombres entre eux et pour séparer la partie entière du nombre de sa partie non entière. Je ne sais pas d'où sort ton fichier CSV, mais on utilise souvent le point virgule pour séparer le contenu des différentes cellules. Ensuite pour pouvoir faire un fscanf, il faut que le flottant contienne un point au lieu d'une virgule.
    123.456 -> correct
    123,456 -> non correct

    Ce sont deux problèmes connus, et si c'est possible, on essaie de les traiter en amont du programme en C... C'est à dire à la génération du CSV.

    A+

    Pfeuh

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 3
    Par défaut
    Je me suis peut être mal exprimé

    Je cherche simplement à sauvegarder la première colonne de mon fichier CSV dans un tableau, tout simplement.

    Citation Envoyé par pfeuh Voir le message
    Salut,

    Tu ne peux pas utiliser le même séparateur (ici la virgule) pour séparer à la fois les nombres entre eux et pour séparer la partie entière du nombre de sa partie non entière. Je ne sais pas d'où sort ton fichier CSV, mais on utilise souvent le point virgule pour séparer le contenu des différentes cellules. Ensuite pour pouvoir faire un fscanf, il faut que le flottant contienne un point au lieu d'une virgule.
    123.456 -> correct
    123,456 -> non correct

    Ce sont deux problèmes connus, et si c'est possible, on essaie de les traiter en amont du programme en C... C'est à dire à la génération du CSV.

    A+

    Pfeuh
    Je peux peut être m'arranger pour que le dispositif en question génère des fichiers CSV de la manière suivante :
    123.456;500
    123,456;501
    etc ...

    Si le fichier généré a cette forme, quel genre de syntaxe je peux utiliser dans le fscanf pour uniquement sauvegarder la première colonne ?

    Merci pour vos réponses précédentes !

  5. #5
    Membre éclairé Avatar de LinuxUser
    Inscrit en
    Avril 2007
    Messages
    857
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 857
    Par défaut
    Oui mais pfeuh te fais remarquer que ton fichier CSV est mal foutu car ton séparteur est la virgule alors que les nombres sont également représentés avec des virgules:

    Si on parse cette ligne on aura :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     0 :15322
     1 : 000
     2 : 17800
     3 : 000
    Je crois pas que c'était le résultat attendu.

    Il faudrait avoir :
    Ou

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 3
    Par défaut
    C'est tout à fait juste, je suis d'accord sur le fait que ce type de fichier CSV est très mal formaté.

    Jusqu'à présent pour traiter ces données, cela n'a pas posé de problèmes car nous avons fait nos programmes sous matlab, qui ne pose pas de problème sur ça (il accepte de prendre la première colonne correctement sans erreur).

    Seulement, pour des soucis de rapidité, j'ai besoin de passer une partie du code en langage C, mais je me heurte au problème de gérer les séparateurs entre les valeurs.

    Je vais tenter de corriger le programme du dispositif qui génère ces fichiers CSV afin qu'ils génèrent ce type de fichier :

    121,600;500
    122,000;500
    etc ..

    (je pense que peut être la virgule est mieux pour séparer les unités des décimales, car il peut arriver que l'on ai besoin de passer les valeurs dans excel, qui n'accepte que les virgules pour les décimales).

    Si j'obtiens un fichier de ce type, pourriez vous simplement m'indiquer la marche à suivre pour sauvegarder seulement la première colonne svp ?

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 498
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 498
    Billets dans le blog
    1
    Par défaut
    Tu peux utiliser fscanf() pour récupérer un float et ignorer le reste de la ligne. On a parle de ce genre de choses récemment : http://www.developpez.net/forums/d13...ne-caracteres/

  8. #8
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,

    Citation Envoyé par Maxxie12 Voir le message
    je pense que peut être la virgule est mieux pour séparer les unités des décimales, car il peut arriver que l'on ai besoin de passer les valeurs dans excel, qui n'accepte que les virgules pour les décimales
    C'est toi qui voit, mais la virgule n'est pas le séparateur natif. En C, c'est le point, en Excel, c'est la virgule... Or ici, on fait du C. Et ce sera pareil en python, java, php et la majorité les langages.... Et peut-être même en microsoft VB! Il faut vraiment considérer Excel comme une exception, surtout pas comme le cas général. De toute façon, un fscanf %f ne marchera qu'avec un point.

    A+

    Pfeuh

  9. #9
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par pfeuh Voir le message
    De toute façon, un fscanf %f ne marchera qu'avec un point.
    Est-ce que cela ne dépend pas plutôt de la locale utilisée ?

  10. #10
    Membre actif Avatar de Mipwiq
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2013
    Messages : 42
    Par défaut
    Si tu avais utilisé un file descriptor et read, je t'aurais conseillé d'utiliser lseek pour te déplacer dans ton fichier.

    Mais là je ne sais pas si il y a un équivalant avec un stream
    Essai au pire de récupérer toute la ligne et en suite de parser toi même la chaine de caractère pour ne garder que le résultat que tu cherche.

  11. #11
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Mipwiq Voir le message
    Si tu avais utilisé un file descriptor et read, je t'aurais conseillé d'utiliser lseek pour te déplacer dans ton fichier.

    Mais là je ne sais pas si il y a un équivalant avec un stream
    Bien sûr, on a fseek

  12. #12
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Est-ce que cela ne dépend pas plutôt de la locale utilisée ?
    Euh... Je bosse dans l'embarqué, du C bien roots. La locale, ça sort de mes compétences.

    De ce que je viens d'en googler, la locale sert essentiellement à la partie graphique du système, c'est à dire pour la représentation à l'écran, pas pour sauver ou lire des données. Gérer un fichier de données en fonction de la langue de celui qui l'a écrit, ne serait ce pas se tirer une baller dans le pied?

  13. #13
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par pfeuh Voir le message
    Euh... Je bosse dans l'embarqué, du C bien roots. La locale, ça sort de mes compétences.

    De ce que je viens d'en googler, la locale sert essentiellement à la partie graphique du système, c'est à dire pour la représentation à l'écran, pas pour sauver ou lire des données. Gérer un fichier de données en fonction de la langue de celui qui l'a écrit, ne serait ce pas se tirer une baller dans le pied?
    Je ne suis pas sûr de moi, mais il me semble que selon la locale, l'affichage avec (s/f)(n)printf peut être différent ( pour le séparateur des milliers par exemple ).

    C'est d'ailleurs ce que dit wikipédia :
    These settings usually include the following display (output) format settings:

    Number format setting
    Character classification, case conversion settings
    Date-time format setting
    String collation setting
    Currency format setting
    Paper size setting
    other minor settings ...
    Mais cela m'étonnerais qu'il n'en soit pas de même avec (s/f)scanf, ce serait bizarre de ne pas pouvoir lire un flottant qu'on a écrit avec un fprintf à cause de la locale.
    Personnellement, je n'ai jamais vraiment touché à la locale sauf pour des problèmes d'encodage.

  14. #14
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 817
    Par défaut
    Pourquoi se focaliser sur fscanf ? Perso, je prendrais le fichier tel qu'il m'est fourni, et je sais que le début d'une valeur peut se situer à deux endroits: soit en début de ligne, soit apès une virgule paire. strchr() fera très bien le travail ! La seule condition: que le fichier soit présenté exactement comme dans le 1er post.

Discussions similaires

  1. Lire un fichier .txt et exploiter son contenu
    Par berberat dans le forum MATLAB
    Réponses: 5
    Dernier message: 07/08/2007, 12h38
  2. Réponses: 2
    Dernier message: 19/10/2006, 10h43
  3. Réponses: 8
    Dernier message: 09/07/2006, 15h42
  4. Réponses: 5
    Dernier message: 27/05/2006, 13h06
  5. Réponses: 20
    Dernier message: 23/03/2006, 17h21

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