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 :

Récupérer certaines colonnes d'un fichier CSV


Sujet :

C

  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2022
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2022
    Messages : 1
    Par défaut Récupérer certaines colonnes d'un fichier CSV
    Bonjour à tous,

    Je suis sur un projet pour mes cours, il est presque finalisé, mais j'ai quelques petits problèmes que je ne comprends pas.

    Le but du projet et de récupérer via un fichier CSV des informations selon les colonnes (dans notre cas la colonne 6/76/85e colonnes), de les trier avec les fonctions de tri d'insertion et de sélection, et ne pas les trier, selon un nombre de ligne précis. Ensuite nous devons les remettre dans un fichier csv avec le nombre de lignes analysés et le temps que cela a mis.

    Mon problème est que lorsque mon programme me demande quel tri utiliser, et que je mets "1", il me laisse écrire à l'infini. Du type :
    Quel tri voulez-vous faire ? taper 1 pour sélection taper 2 pour insertion
    1
    1
    1
    1
    2
    5
    6
    bonjour

    Merci d'avance pour votre aide.

    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
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    #include <stdio.h>
    #include <stdbool.h>
    #include <math.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #define MAX 1000000
     
    typedef char string[1024];//def du type de variable string
     
    typedef struct reference {
     
        int AGED;
        long long int SURF;
        string PROF;
     
    }ref;
     
    ref reftab[MAX];
     
    long int limite=0;
     
    void clear_stdin(void)
    {
        int c;
     
        do
        {
            c=getchar();
        } while (c!='\n'&& c!=EOF);
    }
    void triParInsertion() //Permet de trier les données par un tri par insertion
    {
     
        //Déclaration des variables
     
        int cpt; //compteur
        int unit; //stockage temporaire
        int dureeTriInsert; //duree du tri
        long int unit2; //stockage temporaire
        int cpt2; //compteur 2
        string unitPROF;//stockage temporaire pour PROF
        int PROFCOMP;
     
        clock_t debutTriInsert; //2 variables pour le temps de tri
        clock_t finTriInsert;
     
        char TriInsertBuffer[50]; 
        char TriInsertBufferProf[50];
     
        FILE* fdonneesInsertion = fopen("donneeInsertion.csv", "at"); //ouverture/création du fictier csv
     
        for (cpt=0;cpt<50;cpt++) //On met le buffer vide
        {
            TriInsertBuffer[cpt]='\0';
        }
        printf("Tri par insertion......Tri par insertion \n");
        debutTriInsert=clock();
     
        for (cpt=0;cpt<limite;cpt++)//début du tri
        {
            //tri AGED
            unit=reftab[cpt].AGED;
            cpt2=cpt;
            while ((cpt2>0)&&(reftab[cpt2-1].AGED>unit))
            {
                reftab[cpt2].AGED=reftab[cpt2-1].AGED;
                cpt2=cpt2-1;
            }
            reftab[cpt2].AGED=unit;
     
            //tri PROF
            strcpy(TriInsertBufferProf,reftab[cpt].PROF);
            cpt2=cpt;
     
            PROFCOMP=strncmp(reftab[cpt2-1].PROF,TriInsertBufferProf,4);
     
            while( (cpt2 > 0) && (PROFCOMP > 0))
            {
                strcpy(reftab[cpt2].PROF,reftab[cpt2-1].PROF);
                cpt2=cpt2-1;
            }
            strcpy(reftab[cpt2].PROF,TriInsertBufferProf);
     
            //tri SURF
            unit2=reftab[cpt].AGED;
            cpt2=cpt;
            while ((cpt2>0)&&(reftab[cpt2-1].AGED>unit))
            {
                reftab[cpt2].AGED=reftab[cpt2-1].AGED;
                cpt2=cpt2-1;
            }
            reftab[cpt2].AGED=unit2;
        }
        finTriInsert=clock();
     
        //affichage après tri
        for(cpt=0;cpt<limite;cpt++)
        {
            printf("TriInsertionAged=%d TriInsertionProf=%s TriInsertionSurf=%lld \n",reftab[cpt].AGED,reftab[cpt].PROF,reftab[cpt].SURF); //affichage dans le terminal
        }
        dureeTriInsert=(finTriInsert-debutTriInsert)/1000;//calcul du temps
     
        //mise des données dans le fichier csv
        sprintf(TriInsertBuffer,"%d,%d",cpt,dureeTriInsert);
        fprintf(fdonneesInsertion, "%s\n",TriInsertBuffer);
    }
     
    void TriSelection()//permet de triée un tableau en plaçant les éléments par permutations à la fin du tableau
    {
        //ouverture des fichiers
        //Déclaration de variables
        int cpt; //compteur
        int cpt2; //compteur 2
        int unit; //stockage temporaire
        int top; //stockage de la case du tableau top
        long int unit2; //stockage temporaire
        int TriSelectionDuree; //stockage de la durée
        string unitPROF;//stockage temporaire pour PROF
     
        clock_t debutTriSelection;
        clock_t finTriSelection;
     
        char BuffTriSelection[50];
     
        FILE* fdonneesSelection = fopen("donneeSelection.csv", "at");
        //Début
        //Tri SELECTION AGED
        cpt=MAX; //mise au max du compteur pour le décompagte 
        while (cpt>0) 
        {
            top=0;
            for (cpt2=0;cpt2<=cpt;cpt2++)
            {
                if (reftab[cpt2].AGED>reftab[top].AGED)
                {
                    top=cpt2;
                }
            }
            reftab[top].AGED;
            reftab[top].AGED=reftab[cpt].AGED;
            reftab[cpt].AGED=unit;
            cpt=cpt-1;
        }
        //Tri Selection SURF
        cpt=MAX;
        while (cpt>0)
        {
            top=0;
            for (cpt2=0;cpt2<=cpt;cpt2++)
            {
                if (reftab[cpt2].SURF>reftab[top].SURF)
                {
                    top=cpt2;
                }
            }
            unit2=reftab[top].SURF;
            reftab[top].SURF=reftab[cpt].SURF;
            reftab[cpt].SURF=unit2;
            cpt=cpt-1;
        }
        //Tri Selection PROF
        cpt=MAX;
        while (cpt>0)
        {
            top=0;
            for (cpt2=0;cpt2<=cpt;cpt2++)
            {
                if (reftab[cpt2].PROF>reftab[top].PROF)
                {
                    top=cpt2;
                }
            }
            strcpy(unitPROF,reftab[top].PROF); //changement de égal vers strcpy car chaîne de caractères
            strcpy(reftab[top].PROF,reftab[cpt].PROF);
            strcpy(reftab[cpt].PROF,unitPROF);
            cpt=cpt-1;
        }
        for(cpt=0;cpt<limite;cpt++)
        {
            printf("TriInsertionAged=%d TriInsertionProf=%s TriInsertionSurf=%lld \n",reftab[cpt].AGED,reftab[cpt].PROF,reftab[cpt].SURF); //affichage dans le terminal
        }
        TriSelectionDuree=(finTriSelection-debutTriSelection)/1000;//calcul du temps
     
        //Mise dans le fichier csv
        sprintf(BuffTriSelection,"%d,%d",cpt,TriSelectionDuree);
        fprintf(fdonneesSelection, "%s\n",BuffTriSelection);
    }
     
    int main()
    {
        //Déclaration de variables
        int cpt;
        int cpt_2;
        int cpt_struct;
        char element[1024];
        char buffer[50];
        int chiffre=-1;
        int x;
        int i;
        int rep;
     
        for (cpt=0; cpt < 1024; cpt++)
        {
            element[cpt] = '\0';
        }
     
        //ouverture des fichiers
        FILE* f = fopen("FD_INDREGZD_2018.csv","r");
        FILE* fdonnees = fopen("donnee.csv", "at");
     
        if ((f==NULL)) 
        {
            //Indique si il y a une erreur d'ouverture de fichier
            printf("Erreur d'ouverture de fichier \n");
        }
        else
        {
            while (chiffre<0)
            {
                    printf("Rentrer un multiple supérieur ou égal à 0 pour le nombre de ligne à analyser \n");
                    scanf("%d",&chiffre);
            }
            clear_stdin();
            limite=chiffre*10000;
     
            clock_t debut=clock(); //nombre pas processeur seconde
     
            cpt_struct=0;//permet de réinitialiser
            x=0;
     
            while ((fgets(element, 1024 ,f)!=NULL) && (x<limite ))
            { 
                for (i=0; i<strlen(element);i++)
                {
                    if (element[i]==';')
                    {
                        element[i]=' ';
                    }
                }
     
            //récupération des bonnes colonnes
            sscanf(element, "%*d%*d%*d%*d%*d%d", &reftab[cpt_struct].AGED);
            sscanf(element, "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%s",reftab[cpt_struct].PROF);
            sscanf(element, "%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%lld", &reftab[cpt_struct].SURF);
            printf("AGED =%d, PROF=%s, SURF=%lld \n",reftab[cpt_struct].AGED,reftab[cpt_struct].PROF,reftab[cpt_struct].SURF);
     
            cpt_struct++;
            x++;
            }
     
        clock_t fin=clock();
     
        //calcul du temps en secondes
        int duree=(fin-debut)/1000;
        printf("La durée d'éxecution est de %d millisecondes pour %d lignes",duree,x);
     
        //intégration au fichier csv
        sprintf(buffer,"%d,%d",cpt_struct,duree);
        fprintf(fdonnees, "%s\n",buffer);
     
        printf("Quel tri voulez-vous faire ? taper 1 pour sélection taper 2 pour insertion \n");
        scanf("%d",&rep);
        clear_stdin();
        while ((rep > 2)|| (rep<1))
        {
            printf("Quel tri voulez-vous faire ? taper 1 pour sélection taper 2 pour insertion \n");
            scanf("%d",&rep);
            clear_stdin();
        }
        if (rep==1)
        {
                TriSelection();
        }
        else if (rep==2)
        {
                triParInsertion();
        }
        else 
        {
            printf("Impossible \n");
        }
        return 0;
    }
        fclose(f);
        fclose(fdonnees);

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Bonour
    Déjà ce serait bien que tu ne tentes pas de fermer le fichier dans le cas où il n'a pas été ouvert.
    Ensuite écrire en C c'est comme écrire une partition: ça doit être lisible. Et pour que du C soit lisible, en plus de l'aération entre les différents termes d'instruction, exemple ce while((cpt2>0)&&(reftab[cpt2-1].AGED>unit)). Tu penses que plus c'est serré plus ça ira vite??? => while (cpt2 > 0 && reftab[cpt2-1].AGED > unit) (je ne t'embête pas sur les parenthèses inutiles, personne n'est tenu de connaître les 15 niveaux de priorité du C par coeur même s'il semble évident qu'un connecteur logique sera moins prioritaire qu'un opérateur de relation d'ordre).
    Mais donc en dehors de l'aération, ce sont les tabulations qui permettent de bien voir quel bloc sera associé à quelle boucle ou condition. Déjà par exemple tu verrais que ton main() n'est pas terminé.

    Sinon pour ton erreur ben chez-moi ton code fonctionne. C'est à dire qu'il n'y a pas d'erreur. Probablement parce que je suis sous Linux, OS écrit en C et donc dans lequel le C est parfaitement adapté à communiquer, tandis que toi tu dois probablement tourner sur un autre OS (exemple zindow), OS dans lequel le C n'est que "rajouté" et donc probablement moins bien compris. D'ailleurs cette valeur "at" dans le fopen() que je ne connais pas me laisse penser qu'effectivement tu n'es pas sur un vrai OS/C ("t" veut-il dire "texte" ???)
    Toutefois ce que tu décris (qui n'a d'ailleurs absolument rien à voir avec le titre de ce topic ce qui est donc trompeur pour les visiteurs du forum) est habituel d'un souci stdin. Il est probable que ta fonction clear_stdin() ne marche pas parfaitement bien. Et donc chaque scanf() suivant lit le contenu du stdin précédent au lieu d'attendre que tu tapes un nombre au clavier.

    Ce qui m'amène au second point: la gestion de stdin et cette fonction que tu as codé et qu'on voit fleurir assez souvent, montrée généralement par des profs plus ou moins compétents qui enseignent le C sans l'avoir eux-même vraiment bien compris (un aveugle qui en guide un autre le long d'une falaise). Et encore ça reste quand-même relativement propre face à l'autre solution fflush(stdin) qui, elle, est carrément à jeter (fflush est fait pour finaliser des écritures, or stdin ce n'est pas un buffer d'écriture).
    Donc stdin c'est un buffer, qui a exactement les mêmes droits que tout autre buffer (un fichier par exemple). Si on te demandait de lire et traiter un fichier, est-ce qu'il te viendrait à l'idée de commencer par le vider pour te simplifier la vie?
    Donc voilà, ne fais pas à stdin ce que tu ne ferais pas à un fichier. stdin c'est un buffer, mais ça peut être aussi un canal de communication avec par exemple un autre programme X qui créerait de l'info et qui enverrait cette info à ton programme. Et toi, ben l'info tu la jettes !!!

    Donc stdin ne se purge pas, ça se gère. Ca nécessite de le connaitre, de lui parler, de le caresser dans le sens du poil, de savoir ce qui s'y passe surtout quand tu saisis ton nombre. Quand tu entres (par exemple) "2" pour choisir le menu 2, tu termines ta saisie par un <return> pour la valider. Or ce <return> (codé '\n') est lui aussi stocké dans stdin. Ensuite scanf() récupère le nombre via le "%d" mais laisse le '\n' dans stdin. Et voilà, ton stdin est foiré et toute saisie suivante récupèrera le '\n' précédent sans laisser à l'utilisateur la possibilité de taper un truc.

    La solution immédiate (et pas forcément mauvaise) est donc de supprimer ce '\n' de trop (ça c'est de la gestion, pas de la purge) en rajoutant un fgetc(stdin) juste après le scanf. Mais ça ne gèrera pas le cas où tu tapes "123abcdef" (tu supprimes le 'a' mais pas le reste).
    Certains maitrisent aussi pas mal le scanf et arrivent à formaliser cette suite de lettres et '\n' via des syntaxes style scanf("%d[.*]\n") ou autres.

    Ou alors tu crées une fonction dédiée à récupérer un int et qui commence par récupérer une chaine. En récupérant la chaine, ça récupère le nombre mais aussi tout le reste et stdin reste clean et ensuite tu peux traiter la chaine pour en extraire le nombre et le renvoyer (ou faire re-saisir si pas de nombre trouvé)

    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int saisie(const char* const prompt) {
    	char input[1024 + 1];
    	int r;
    	while (1) {
    		fputs(prompt, stdout);
    		fflush(stdout);
    		fgets(input, 1024 + 1, stdin);
    		if (sscanf(input, "%d", &r) == 1) break;
    		fputs("Erreur de saisie, recommencez\n", stdout);
    	}
    	return r;
    }

    Ensuite, tu remplaces ton scanf() par ceci
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while (1) {
       	rep=saisie("Quel tri voulez-vous faire ? 1 pour sélection, 2 pour insertion :");
    	if (rep == 1 || rep == 2) break;
    	printf("Choix %d incorrect, 1 ou 2 !!!\n", rep);
    }

    Ah, dernier détail: utiliser des variables globales juste pour ne pas avoir à réfléchir à comment se communiquer les infos entre les fonctions, c'est mal.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Réponses: 6
    Dernier message: 18/05/2015, 10h57
  2. Récupérer une colonne d'un fichier CSV à l'aide de l'entête
    Par drake56 dans le forum Windows Forms
    Réponses: 5
    Dernier message: 06/01/2010, 20h23
  3. Réponses: 4
    Dernier message: 13/12/2006, 17h10
  4. Réponses: 3
    Dernier message: 26/04/2006, 11h52
  5. [débutant] nombre de colonne dan sun fichier csv
    Par mandagor dans le forum C++
    Réponses: 18
    Dernier message: 15/06/2005, 15h42

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