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 :

Supprimer les lignes en double d'un fichier csv


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 39
    Par défaut Supprimer les lignes en double d'un fichier csv
    salut tous
    je cherche a Supprimer les lignes en double d'un fichier texte (csv)
    exemple

    1;aaa;0;1;
    1;aaa;0;1;
    0;aaa;1;0;
    1;aaa;0;1;
    1;bbb;0;1;
    0;aaa;1;0;
    1;aaa;0;1;
    1;bbb;0;1;

    et merci

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 309
    Billets dans le blog
    5
    Par défaut
    Bonjour.

    Pour résoudre ce type de problème il faut se poser une première question et surtout y répondre avant de se lancer :
    • Le fichier traité pourra-t-il avoir une taille importante?

    En fonction de la réponse on aura déjà une première approche :
    • OUI : la recherche de doublons ne pourra se faire qu'en lisant le fichier directement sur le disque,
    • NON : on pourra charger complètement le fichier en mémoire pour traitement.

    Ensuite, comment écrire le fichier ? On continue sur la même lancée :
    • Si le fichier est important (donc pas en mémoire) on créera un fichier temporaire qui correspondra au fichier final. Une fois terminé on efface l'original et on le remplace par le temporaire,
    • Si le fichier original est chargé en mémoire on crée le fichier final toujours en mémoire. On écrasera au final l'original avec.

  3. #3
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    J'ai une autre question importante qui me vient à l'esprit.

    • à partir de quelle taille peut-on dire qu'un fichier est de taille importante?

  4. #4
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 309
    Billets dans le blog
    5
    Par défaut
    Oui en effet on peut se la poser .

    Pour ma part j'y réponds comme ca. Si je développe une application qui traite un fichier dont je ne connais absolument pas la variation de taille je considère dés le départ qu'il sera important.

    Ca me rappelle un bogue de Word 2.0 il y a quelques années (voir ce lien) où il était impossible d'enregistrer des fichiers trop volumineux. Les développeurs n'avaient pas anticiper ce type d'utilisation.

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 484
    Par défaut
    Citation Envoyé par gerald3d Voir le message
    Pour résoudre ce type de problème il faut se poser une première question et surtout y répondre avant de se lancer :

    — Le fichier traité pourra-t-il avoir une taille importante?
    La première question à se poser, à mon avis, est « faut-il supprimer tous les doublons ou uniquement les lignes consécutives » ? Parce que, dans ce dernier cas, l'opération est nettement plus facile à réaliser.

    Citation Envoyé par info help Voir le message
    salut tous je cherche a Supprimer les lignes en double d'un fichier texte (csv) exemple
    Est-ce que c'est un exercice scolaire à réaliser impérativement en C ou cherches-tu réellement à supprimer les doublons d'un fichier ? Parce que dans ce dernier cas, si tu travailles sous Unix, il y a sort et uniq pour faire ça facilement depuis le shell (c'est un cas de figure très fréquent).

  6. #6
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    La première question à se poser, à mon avis, est « faut-il supprimer tous les doublons ou uniquement les lignes consécutives » ? Parce que, dans ce dernier cas, l'opération est nettement plus facile à réaliser.
    Oui mais autant partir du principe du "Qui peut le plus, peut le moins"

    Ta première solution (difficile) permet de gérer les lignes consécutives, alors que dans le cas inverse, on est chocolat

    Est-ce que c'est un exercice scolaire à réaliser impérativement en C ou cherches-tu réellement à supprimer les doublons d'un fichier ? Parce que dans ce dernier cas, si tu travailles sous Unix, il y a sort et uniq pour faire ça facilement depuis le shell (c'est un cas de figure très fréquent).
    Dans un langage de script, c'est effectivement plus simple, mais ce genre d'exercice en C m'intéresse, je me vois bien le tenter afin de progresser

  7. #7
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Alors la question que l'on doit aussi se poser est si l'opération doit être stable ou non. L'ordre des éléments a-t-il une importance ? Si la première occurence d'une ligne dans le fichier d'origine apparaît avant une autre ligne, cela doit-il aussi être le cas dans le fichier amaigri ?

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 484
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Oui mais autant partir du principe du "Qui peut le plus, peut le moins" Ta première solution (difficile) permet de gérer les lignes consécutives, alors que dans le cas inverse, on est chocolat
    Oui mais justement : les deux approches sont très différentes en matière de complexité. Donc soit c'est un exercice scolaire et, dans ce cas, il faut être très clair sur ce que veut le prof' parce que l'objectif à court terme n'est probablement pas de réécrire un monument tout de suite, soit c'est un réel cas de figure et dans ce cas, ce n'est pas la peine d'embarquer le primo-postant dans quelque chose qui n'est pas son objectif final.

    Mais surtout : il y a une grande différence entre éliminer les répétitions consécutives d'une même ligne et supprimer toutes ses occurrences au sein d'un fichier. L'exemple-type est le fichier de log : si on a n fois le même message, on peut le factoriser. Par contre, si on a un message « x » puis un message « y » puis à nouveau un message « x », alors l'ordre d'apparition de ses messages a une importance ! Et c'est probablement le cas aussi du fichier *.csv du primo-postant. Et ce n'est même pas seulement une question de stabilité de tri dans ce cas : le fait d'avoir reçu un message différent implique la réapparition légitime du premier message dans le fichier de sortie.

    Et comme, enfin, la suppression globale des lignes redondantes implique forcément un tri, alors l'approche du shell UNIX est la meilleure : faire d'un côté un outil de tri, de l'autre côté un outil (trivial) de suppression des lignes consécutives, avec possibilité de combiner les deux pour arriver à ses fins.

  9. #9
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    @obsidian

    En effet c'est complexe, du coup je m'en suis fais un défi, je trouve cet exercice intéressant question apprentissage.

    Je présente mon code, il est loin d'être parfait, les exceptions ne sont pas encore tapées, mais il est fonctionnel.

    J'ai un seul soucis que je ne suis pas sûr pouvoir résoudre, je lis le texte d'un fichier à l'aide de gedit, et j'ai un résultat pas très lisible

    Bonjour
    \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00!\00\00\00\00\00\00\00Coucou
    \00\00\00\00\00\00\00\00\00Coucou
    \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00!\00\00\00\00\00\00\00Salut
    \00\00\00\00Salut
    \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00!\00\00\00\00\00\00\00HellHello
    \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00!\00\00\00\00\00\00\00Bye
    Bye
    \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00Tchao
    \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00
    Qui n'est bien sûr pas le résultat attendu !!!

    Voici mon code

    test.c

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "test.h"
     
    #define MAX 80
     
    void ajouter(tab *tableau, char *ligne)
    {
        tableau->table[tableau->len] = malloc((strlen(ligne)+1) * sizeof(char));
        strcpy(tableau->table[tableau->len], ligne); /* copie de ligne dans la liste */
        tableau->len++; /* la longueur de la liste augmente de 1 */
    }
     
    void afficher(tab *tableau)
    {
        int i=0;
        for(; i<tableau->len; i++)
        {
            printf("ligne %d --> %s\n", i+1, tableau->table[i]);
        }
    }
     
    int rechercher(tab *tableau, char *ligne)
    {
        int i=0;
        if (tableau == NULL || tableau->table == NULL)
        {
            puts("Pas de doublons dans le fichier");
            exit(1);
        }
        for(; i<tableau->len; i++)
        {
            if (strcmp(tableau->table[i], ligne) == 0) return 1; /* Pour chaque chaine de la liste, je compare à la ligne, si doublon on retourne 1 */
        }
        return 0; /* sinon 0 */
    }
     
    void lire(FILE *fic, tab *tableau)
    {
        char line[MAX];
        if (fic == NULL)
        {
            puts("Erreur de lecture du fichier\n");
            exit(1);
        }
        while (fgets(line, MAX, fic) != NULL) /* Tant que pas la fin du fichier je lis la ligne suivante */ 
        {
            if (rechercher(tableau, line) == 0) ajouter(tableau, line); /* Si pas de doublon, j'ajoute la chaine dans la liste */
        }
    }
     
    void ecrire(tab *tableau, FILE *fic) /* Ecriture des éléments de la liste dans le fichier fic */
    {
        int i=0, n=0;
        char *element;
        if (fic == NULL)
        {
            puts("Erreur lors de l'écriture\n");
            exit(1);
        }
        for(; i<tableau->len; i++)
        {
            element = tableau->table[i];
            n = strlen(element);
            fwrite(element, n * sizeof(element), 1, fic);
        }
    }
     
    tab *creer()
    {
        tab *new = malloc(sizeof(tab)); /* On alloue de la mémoire pour le nouveau tableau */
        new->table = malloc(MAX * sizeof(char)); /* On alloue pour la chaine dont on ne connait pas sa longueur */
        new->len = 0; /* Longueur nulle à la création */
        if (new == NULL || new->table == NULL)
        {
            puts("Erreur d'allocation mémoire");
            exit(1);
        }
        return new; /* On retourne la liste vide */
    }
     
    void detruire(tab *tableau)
    {
        int i;
        if (tableau != NULL)
        {
            for(i=0; i<0; i++)
            {
                free(tableau->table[i]); /* nettoyage de chacun des éléments */
            }
            free(tableau->table);
            free(tableau);
        }
    }
     
    int main(void)
    {
        tab *T = creer();
        FILE *fichier;
        FILE *fichier_temp;
        fichier = fopen("/home/fred1599/Desktop/test.txt", "r");
        fichier_temp = fopen("/home/fred1599/Desktop/test_temp.txt", "w");
        lire(fichier, T);
        afficher(T);
        ecrire(T, fichier_temp);
        detruire(T);
        return 0;
    }
    test.h

    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
    #ifndef TEST_H_INCLUDED
    #define TEST_H_INCLUDED
     
     
    typedef struct
    {
        char **table;
        int len;
    } tab;
     
    void ajouter(tab *tableau, char *ligne);
    void afficher(tab *tableau);
    tab *creer();
    int rechercher(tab *tableau, char *ligne);
    void ecrire(tab *tableau, FILE *fic);
    void lire(FILE *fic, tab *tableau);
    void detruire(tab *tableau);
     
     
    #endif
    Bref c'était chaud, je suis un peu naze, du coup j'ai pu passer à côté de quelque chose...

    Je crois ne pas avoir bien compris la fonction fwrite (doute )

    Edit : J'ai fais une modification dans la fonction écrire.
    Edit 2 : Quelques exceptions de rajouter
    Edit 3 : Fonction nommée creer() au lieu de create() et modif fonction affichage()
    Edit 4 : Rajout de commentaires

    Merci par avance,

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

Discussions similaires

  1. Supprimer les lignes en double dans un fichier texte
    Par SilkyRoad dans le forum Contribuez
    Réponses: 1
    Dernier message: 01/05/2017, 15h09
  2. Réponses: 14
    Dernier message: 22/09/2011, 16h11
  3. Supprimer les lignes en double
    Par illight dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 13/09/2007, 19h43
  4. Supprimer les lignes d'un fichier texte
    Par radhwene dans le forum Langage
    Réponses: 1
    Dernier message: 20/06/2007, 11h01
  5. Réponses: 2
    Dernier message: 04/05/2006, 13h10

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