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 :

Nombre de lignes d'un fichier et comparaison des deux fichiers


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 122
    Points : 66
    Points
    66
    Par défaut Nombre de lignes d'un fichier et comparaison des deux fichiers
    Bonjour,

    Je souhaite lire deux fichier, compter le nombre de lignes de chaque fichier et vérifier si les deux fichier sont cohérents (c'est-à-dire que le nombre de lignes du fichier 1 doit être égal au nombre de lignes du fichier 2) avant d'effectuer les calculs sur les données contenant dans ces fichiers.

    Voici un bout de code ou plutôt la fonction censée faire ce que je souhaite et je vous fait part juste après des réponses du programme :
    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
     
     
    void vnlignes_fichiers(const char *fichier1, const char *fichier2)
    {
    int c1,c2;
    int  nligfich1=0,nligfich2=0;
     
     
    FILE *fich1;
    FILE *fich2;
     
    fich1=fopen(fichier1,"r");
     
    if (fich1 != NULL){
     
    while ((c1 = getc(fich1)) != EOF){
        if (c1 == '\n')
            ++nligfich1;
    }
     
    fclose(fich1);
     
    }
    else{
     
    	fprintf(stdout,"\n");
    	fprintf(stdout,"****************************************************************\n");
    	fprintf(stderr,"Attention erreur : fichier  %s  introuvable \n",fich1);
           fflush(stderr);
    	fprintf(stdout,"****************************************************************\n");
    	fprintf(stdout,"\n");
     
    	exit(10);
    }
     
     
     
    fich2=fopen(fichier2,"r");
     
    if (fich2 != NULL){
     
    while ((c2 = getc(fich2)) != EOF){
        if (c2 == '\n')
            ++nligfich2;
    }
     
     
    fclose(fich2);
     
    }
    else{
     
    fprintf(stdout,"\n");
    	fprintf(stdout,"****************************************************************\n");
    	fprintf(stderr,"Attention erreur : fichier  %s  introuvable \n",fich2);
    fflush(stderr);
    	fprintf(stdout,"****************************************************************\n");
    	fprintf(stdout,"\n");
     
    	exit(11);
    }
     
     
     
     if(nligfich1!=nligfich2){fprintf(stderr,"Attention erreur : le nombre de lignes du fichier %s doit etre egal au nombre de lignes du fichier %s \n",fich1,fich2);
     
    fprintf(stdout,"nombre de lignes fichier 1 : %d\n",nligfich1);
     fprintf(stdout,"nombre de lignes fichier 2 : %d\n",nligfich2);
     
     exit(12);
     }
     else{
     
     fprintf(stdout,"Fichiers %s et %s correctes\n",fich1,fich2);
     
     }
     
    }
    Voici les deux fichiers :

    fichier1.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    0.0001
    0.0001
    0.
    0.
    0.
    0.
    0.
    0.
    fichier2.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    1.0
    -1.0
    0.0
    0.0
    0.0
    0.0
    0.0
    0.0
    Les résultats renvoyés sont les suivants :

    Nombre de lignes du fichier 1 : 0
    Nombre de lignes du fichier 2 : 8

    Ma question est la suivante :

    Pourquoi les deux résultats sont différents? Le nombre de lignes est le même dans les deux cas. Pourtant, si j'oublie ce test préliminaire, les résultats sur les opérations effectuées avec les données de ces fichiers sont correctes donc les données sont bien lues. Le but ici étant simplement de compter le nombre de lignes des deux fichiers et de comparer les résultats.

    Si quelqu'un peut m'aider à comprendre ce problème. Merci d'avance.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Attention, il y a quelques bugs dans ton programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	fprintf(stderr,"Attention erreur : fichier  %s  introuvable \n",fich1);
           fflush(stderr);
     
    …
     
    	fprintf(stderr,"Attention erreur : fichier  %s  introuvable \n",fich2);
    fflush(stderr);
     
    …
     
            fprintf(stdout,"Fichiers %s et %s correctes\n",fich1,fich2);

    À chaque fois, tu passes le descripteur du fichier ouvert par fopen() et pas son nom ! Il faut mettre « fichier1 » et « fichier2 » à la place. Par contre, ça n'explique pas pourquoi ton compte ne tombe pas juste. Comme tu comptes les retours à la ligne, il est possible qu'il n'y en ait pas à la fin de la dernière. Par contre, ça donnerait « 7 » et pas zéro.

    D'où proviennent tes fichiers ? Il est possible qu'ils utilisent des caractères spéciaux.

    Enfin, si l'unique but est de compter les lignes d'un fichier à fins de contrôles, et pas spécialement de travailler en C, alors il existe pleins d'outils sous Unix en ligne de commande, comme « wc » (Word Count). Par exemple, « wc -l * » te donnera instantanément le nombre de lignes de chaque fichier contenu dans le répertoire courant.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 122
    Points : 66
    Points
    66
    Par défaut
    Le problème est que je ne peux que poster un bout de code. En variables globales j'ai les noms des deux fichiers déclarés comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char nomfichier1[50]
    char nomfichier2[50]
    ensuite j'ai une fonction qui se charge de lire les noms de ces fichiers dans le bon répertoire.

    Après dans le programme principal, je fais appel à la fonction (comme montré ci-dessous) en lui donnant en paramètres d'entrée les noms des fichiers à lire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nlignes_fichiers(nomfichier1, nomfichier2)
    Pour simplifier, le code va ressembler à ç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
    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
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <string.h>
    char nomfichier1[50]
    char nomfichier2[50]
    void LireNomFichier(void);
    void vnlignes_fichiers(const char *fic1, const char *fic2);
     
    main()
    {
    LireNomFichier(); /* la fonction n'est pas donnée ici mais les bons fichiers sont passés à la fonction permettant de compter le nombre de lignes */
    nlignes_fichiers(nomfichier1, nomfichier2)
    return EXIT_SUCCESS;
     
    }
     
    void vnlignes_fichiers(const char *fichier1, const char *fichier2)
    {
    int c1,c2;
    int  nligfich1=0,nligfich2=0;
     
     
    FILE *fich1;
    FILE *fich2;
     
    fich1=fopen(fichier1,"r");
     
    if (fich1 != NULL){
     
    while ((c1 = getc(fich1)) != EOF){
        if (c1 == '\n')
            ++nligfich1;
    }
     
    fclose(fich1);
     
    }
    else{
     
        fprintf(stdout,"\n");
        fprintf(stdout,"****************************************************************\n");
        fprintf(stderr,"Attention erreur : fichier  %s  introuvable \n",fich1);
           fflush(stderr);
        fprintf(stdout,"****************************************************************\n");
        fprintf(stdout,"\n");
     
        exit(10);
    }
     
     
     
    fich2=fopen(fichier2,"r");
     
    if (fich2 != NULL){
     
    while ((c2 = getc(fich2)) != EOF){
        if (c2 == '\n')
            ++nligfich2;
    }
     
     
    fclose(fich2);
     
    }
    else{
     
    fprintf(stdout,"\n");
        fprintf(stdout,"****************************************************************\n");
        fprintf(stderr,"Attention erreur : fichier  %s  introuvable \n",fich2);
    fflush(stderr);
        fprintf(stdout,"****************************************************************\n");
        fprintf(stdout,"\n");
     
        exit(11);
    }
     
     
     
     if(nligfich1!=nligfich2){fprintf(stderr,"Attention erreur : le nombre de lignes du fichier %s doit etre egal au nombre de lignes du fichier %s \n",fich1,fich2);
     
    fprintf(stdout,"nombre de lignes fichier 1 : %d\n",nligfich1);
     fprintf(stdout,"nombre de lignes fichier 2 : %d\n",nligfich2);
     
     exit(12);
     }
     else{
     
     fprintf(stdout,"Fichiers %s et %s correctes\n",fich1,fich2);
     
     }
     
    }
    Les deux fichiers sont joints. Jusque là je ne vois pas où est le problème et donc je ne comprends pas pourquoi ce résultat. Il n'y a pas de caractères spéciaux dans les fichiers. La lecture en ligne de commande est possible, mais j'ai un grand code avec un grand nombre de modules... inclure ce test dans le programme serait mieux. Merci à toi d'avoir réfléchi au problème.
    Fichiers attachés Fichiers attachés

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    Eh bien, il semble que cela vienne bien de tes fichiers :

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ xxd fich1alire.txt
    0000000: 3130 2e30 3030 310d 3130 2e30 3030 310d  10.0001.10.0001.
    0000010: 302e 300d 302e 300d 302e 300d 302e 300d  0.0.0.0.0.0.0.0.
    0000020: 302e 300d 302e 300d                      0.0.0.0.

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ xxd fich2alire.txt
    0000000: 312e 300a 2d31 2e30 0a30 2e30 0a30 2e30  1.0.-1.0.0.0.0.0
    0000010: 0a30 2e30 0a30 2e30 0a30 2e30 0a30 2e30  .0.0.0.0.0.0.0.0
    0000020: 0d0a                                     ..

    • '\r' correspond au caractère 13 (0Dh) et signifie « Carrier Return ». Il sert à retourner en début de ligne ;
    • '\n' correspond au caractère 10 (0Ah) et signifie « New Line ».


    Sauf que dans l'ASCII, le 10 (0Ah) correspond à VT (« Vertical Tabulation ») et sert à passer une ligne sur le périphérique de sortie (imprimante, télex, teletype, …) mais pas spécialement à ramener le chariot en début de ligne.

    Du coup, sous Unix, c'est implicite, et les terminaux peuvent être réglés pour le faire où pas. Le '\n' est donc le marqueur officiel de fin de ligne dans un fichier texte. Sous D.O.S. et Windows (et même sous les BASIC Microsoft de 1980), une fin de ligne est symbolisée par les deux caractères consécutifs 0Dh 0Ah, donc retour en début de ligne puis saut de ligne, comme sur une machine à écrire. C'est explicite, mais c'est plus ennuyeux à gérer dans un programme C.

    L'ennui, c'est que tu ne devrais pas avoir de 0Dh seuls sans 0Ah, comme c'est le cas dans ton premier fichier. Un éditeur de texte est capable de comprendre que dès que l'on rencontre l'un ou l'autre, on va à la ligne, mais un programme C au sens strict ne rencontrera jamais le caractère '\n' dans ton premier fichier, et ne le comptabilisera jamais.

    Cela nous pose donc la question de la provenance de tes deux fichiers.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 122
    Points : 66
    Points
    66
    Par défaut
    Je ne remercie beaucoup pour cette impressionnante démonstration. Je ne pouvais pas imaginer que ça pouvais venir de l'un des fichiers. En fait le problème ne venait même pas du contenu du fichier 1, puisque quelles que soient les valeurs la réponse était la même.

    En revanche, tu as raison que la provenance du fichier y était pour quelque chose. Au départ, il s'agissait d'un fichier créer à partir de Notepad++ et sauvegarder avec l'extension .txt. Dans mon programme tout se passait bien, les données étaient correctement lues. Le premier fichier a été crée il y a 10 mois, puisque je travaillais essentiellement avec les mêmes données.

    Ces fichiers sont échangés entres Windows/Linux depuis 10 mois puisque le code tourne aussi bien sous Windows (pour des petits calculs) que sous Linux (Cluster de calcul pour des gros calculs et de gros volumes de données).

    Après ce que tu viens de souligner, j'ai édité un nouveau fichier texte (pour le fichier 1) et tout va bien sous Windows, je vérifie demain sous le Cluster si le test va également fonctionner. C'est vraiment surprenant pour moi, je suis content d'avoir appris quelque chose t'intéressant grâce à toi.

    Merci beaucoup.

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 371
    Points : 23 626
    Points
    23 626
    Par défaut
    C'était un plaisir.
    À ton service. :-)

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 122
    Points : 66
    Points
    66
    Par défaut
    Merci, j'ai passé des heures dessus. J'espère que sous Linux tout ira bien. Je te tiens au courant demain avant de clore le sujet.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 122
    Points : 66
    Points
    66
    Par défaut
    Tout va bien, encore merci pour ton expertise.

    A bientôt !

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 984
    Points
    30 984
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par mecaplus Voir le message
    En revanche, tu as raison que la provenance du fichier y était pour quelque chose. Au départ, il s'agissait d'un fichier créer à partir de Notepad++ et sauvegarder avec l'extension .txt. Dans mon programme tout se passait bien, les données étaient correctement lues. Le premier fichier a été crée il y a 10 mois, puisque je travaillais essentiellement avec les mêmes données.
    Si tes fichiers sont transférés via ftp, alors faut activer le flag "txt" qui indique à ftp d'assurer la conversion des sauts de lignes entre Windows et Unix (utile seulement si le transfert se fait d'un monde vers l'autre bien sûr)
    Si tes fichiers sont amenés par clef usb, alors t'as à ta disposition sous Linux un outil "dos2unix" permettant de convertir ton fichier au format Linux. Et t'as aussi l'outil inverse "unix2dos".

    Quand on pense que tout ce bordel est là parce que 2 types n'ont pas su se mettre d'accord dans les années 1970 ça laisse rêveur...
    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]

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 122
    Points : 66
    Points
    66
    Par défaut
    Bonjour et bonne année,

    Effectivement mes fichiers sont transférés via ftp (FileZilla) mais je ne sais pas comment activer le flag "txt", où se situe t-il?
    En revanche, mes fichiers sont souvent créer avec l'extension ".dat", le problème est-il le même?

    Merci

Discussions similaires

  1. File2Compare: Comparaison de deux Fichiers ligne par ligne
    Par hackoofr dans le forum Vos Contributions VBScript
    Réponses: 0
    Dernier message: 13/12/2011, 14h48
  2. Macro VBA Excel : Comparaison des deux 1ères colonnes de 2 fichiers Excel
    Par techneric dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 10/01/2007, 10h00
  3. Comparaison de deux fichiers EXCEL
    Par meufeu dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 18/10/2006, 22h56
  4. comparaison de deux fichiers textes
    Par chmaichel dans le forum Delphi
    Réponses: 1
    Dernier message: 28/07/2006, 11h35
  5. [langage] Comparaison de deux fichiers
    Par perlgirl dans le forum Langage
    Réponses: 4
    Dernier message: 04/05/2005, 16h05

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