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 :

Deux fichiers ouverts: données corrompues ?


Sujet :

C

  1. #1
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut Deux fichiers ouverts: données corrompues ?
    Salut les programmeurs C,
    J'ai écrit un code qui est censé comparer deux fichiers afin de voir combien de lignes sont égales à titre d'exercice :
    fichier: test1
    test
    test
    test
    test
    fichier: test2
    test
    test1
    test
    test
    Et mon code avec un petit print pour illustrer le problème :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define MAXLINESIZE 255
     
     
    main(int argc, char *argv[]) {
      FILE *file_1 ;
      FILE *file_2 ;
      char file_1_stream[MAXLINESIZE] ;
      char file_2_stream[MAXLINESIZE] ;
      int lcr = 0 ; // for line check right
      int lcw = 0 ; // for line check wrong
      if (argc != 3) {
        printf("usage: %s",argv[0]) ;
        exit(1) ;
      }
      else {
        file_1=fopen(argv[1],"r") ;
        file_2=fopen(argv[2],"r") ;
        if ( file_1 == NULL ) {
          printf("unable to open file: %s",argv[1]) ;
          exit(1) ;
        }
        else if ( file_2 == NULL ) {
          printf("unable to open file: %s",argv[2]) ;
          exit(1) ;
        }
      }
      while ( ! ( fgets(file_1_stream,MAXLINESIZE,file_1) == NULL ) || ( fgets(file_2_stream,MAXLINESIZE,file_2) == NULL ) ) {
        int lcc ; // for line check counter
        printf("%s %s\n",file_1_stream,file_2_stream) ; // j'ai trouvé où est l'erreur seulement je ne sais d'où elle vient même avec fopen(argv[1|2]),"rb") j'ai ce problème... 
        size_t len ;
        size_t check ;
     
        check= (strlen(file_1_stream) == strlen(file_1_stream)) ? 1 : 0 ;
        if ( ! check ) {
          lcw++ ;
          continue ;
        }
        else {
          len = strlen(file_1_stream) ;  
          for ( lcc=0 ; file_1_stream[lcc] == file_2_stream[lcc] ; lcc++) {
    	;
          }
     
          if ( ! ( (int) len == lcc+1) ) { 
    	lcw++ ;
    	continue ;
          }
          else {
           lcr++ ;
           continue ;
          }
        }
     
      }
      printf("diff %s %s\nlines equal: %i\nlines wrong: %i\n",argv[1],argv[2],lcr,lcw) ; 
    }
    Le problème semble provenir de l'ouverture du deuxième fichier car j'ai comme sortie :
    test
     //ici un char non imprimable au lieu de "test"
    test
     //ici un char non imprimable au lieu de "test1"
    test
     //ici un char non imprimable au lieu de "test"
    test
    //ici un char non imprimable au lieu de "test"
    diff test1 test2
    lines equal: 0
    lines wrong: 4
    Je ne sais d'où provient le problème…
    J'attends vos réponses éclairées afin d'illuminer mon ignorance.
    Merci.

    PS: j'ai cherché dans la FAQ avant de poster. Rien trouvé.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    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 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Il y a déjà un problème ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        while ( ! ( fgets(file_1_stream,MAXLINESIZE,file_1) == NULL ) || ( fgets(file_2_stream,MAXLINESIZE,file_2) == NULL ) ) {

    « ! » est prioritaire par rapport à « || » et ne s'applique donc qu'à la première condition. Ça veut dire que tu vas entrer dans ta boucle si l'appel au fichier 1 a réussi OU si l'appel au fichier 2 a échoué ! Ou les deux. En outre, si les deux appels échouent, tu entreras aussi dans ta boucle. Et comme tu as écrit « test » à toutes les lignes, tu ne peux pas savoir six la ligne a réellement été lue ou s'il s'agit de l'ancienne ligne inchangée qui se trouvait encore dans le buffer.

  3. #3
    Membre expérimenté Avatar de Ngork
    Homme Profil pro
    Barbare IT
    Inscrit en
    Avril 2009
    Messages
    160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Barbare IT
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 160
    Points : 1 372
    Points
    1 372
    Par défaut
    Pour développer et compléter un peu la réponse d'Obsidian, assez pour répondre complètement à ta question, dans la mesure où le test de chargement de la chaîne 1 réussit toujours, le second test n'a pas lieu et la chaîne 2 n'est donc jamais chargée (et ne peut ensuite évidemment pas être affichée) !

    La solution la plus propre consisterait - à mon avis - à séparer le chargement des chaînes et le test d'entrée dans la boucle, mais faire un ! englobant les deux tests/chargements marchera aussi ... de fait c'est peut-être ce que tu souhaitais faire mais tu as mal placé ta parenthèse, non ?

  4. #4
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci pour vos réponses,
    j'ai effectivement fait une erreurs de syntaxe:
    -dans le while
    et il me reste un soucis il se trouve que la valeur de lcc est érronné après la boucle for:
    pour le mot test elle a pour valeur 8 au lieu 5 = {'t','e','s','t','\n','\0'}.
    Mais je pense que c'est, un problème de buffer, dû au problème le plus grave du problème comme l'a dit Ngork, le test et l'affectation dans la condition de la boucle while.
    Sinon que pensez vous de l'écriture de la boucle for:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for ( lcc=1 ; *file_1_stream == *file_2_stream ; lcc++, ++*file_1_stream, ++*file_1_stream) {
     
    	;
          }
    Merci d'avoir mis en lumière cette faute de syntaxe.
    PS: le programme ne fonctionne toujours pas dû a la valeur érroné de lcc.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        else {
          len = strlen(file_1_stream) ;  
          for ( lcc=0 ; file_1_stream[lcc] == file_2_stream[lcc] ; lcc++) {
    	;
          }
    il n'y a aucune raison que la comparaison s'arrête sur le 0 terminal des chaines et lcc dépend de ce qui se trouve par hasard derrière ce 0. Il faut rajouter dans la condition un test sur le zéro terminal ou sur lcc par rapport à len

    Sinon que pensez vous de l'écriture de la boucle for:
    Qu'elle est fausse.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2013
    Messages : 9
    Points : 26
    Points
    26
    Par défaut
    Salut Luke, j'ai regardé ton code et j'ai vu quelques petites erreurs.
    Comme l'a fait remarqué Obsidian, ton while était faux.
    Ton problème ne venait pas de l'ouverture des fichiers, mais ce que tu en faisais.

    Ensuite, tu t'es extremement compliqué la vie ! Il n'y avait pas besoin d'une deuxime boucle dans le while, et certaines conditions étaient vraiment tarabiscottées ^^'

    Relis ton code en essayant de faire simple, je te poste une petite correction basée sur ton code si tu bloques vraiment
    Je n'ai passé que 5 minutes dessus et n'ai testé qu'avec les memes fichiers tests que toi, j'ai ptet oublié une erreur quelque part.
    J'ai pas le temps de commenter la correction, j'ajoute ça tout à l'heure


    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define MAXLINESIZE 255
     
     
    int             main(int argc, char *argv[])
    {
      FILE          *file_1;
      FILE          *file_2;
      char          file_1_stream[MAXLINESIZE];
      char          file_2_stream[MAXLINESIZE];
      int           lcr, lcw, line = 0;
     
      if (argc != 3)
        {
          fprintf(stderr, "usage: %s file1 file2\n", argv[0]) ;
          exit(1) ;
        }
      file_1 = fopen(argv[1],"r") ;
      file_2 = fopen(argv[2],"r") ;
      if (file_1 == NULL)
        {
          fprintf(stderr, "unable to open file: %s\n", argv[1]) ;
          exit(1) ;
        }
      if (file_2 == NULL)
        {
          fprintf(stderr, "unable to open file: %s\n", argv[2]) ;
          exit(1) ;
        }
      while ((fgets(file_1_stream, MAXLINESIZE, file_1) != NULL) && (fgets(file_2_stream, MAXLINESIZE, file_2) != NULL))
        {
          line++;
          printf("File1 line %d : %s \nFile2 line %d : %s\n", line, file_1_stream, line, file_2_stream);
          if ((strlen(file_1_stream) == strlen(file_2_stream)))
            lcr++;
          else
            lcw++;
        }
      printf("\ndiff %s %s\nlines equal: %i\nlines wrong: %i\n",argv[1],argv[2],lcr,lcw) ;
      return (0);
    }

  7. #7
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci pour vos réponses et votre soutiens,
    pas facile de s'initier au C quand tous est si simple sous python, mais je persiste.

    Concernant le code il suffit d'ajouter une condition d'arrêt dans la boucle de comparaison quand deux lignes sont de longueur égale (mais je ne voulais pas faire cette concession au début) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for ( lcc=0 ; file_1_stream[lcc] == file_2_stream[lcc] ; lcc++) {
    	if ( (int) len == lcc+1 ) {
              break ;
            }
          }
    Afin de rendre mon code fonctionnel (je n'ai pas tester sur de plus gros fichiers que les fichiers de test).

    Mais j'ai essayer de faire mieux en suivant le conseil de Ngork:
    La solution la plus propre consisterait - à mon avis - à séparer le chargement des chaînes et le test d'entrée dans la boucle, mais faire un ! englobant les deux tests/chargements marchera aussi ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    //pseudo code
    int main_loop_bool=1 ;
    while ( main_loop_bool ) {
      void *fb1 = fgets(file_1_stream,MAXLINESIZE,file_1) ; //fb1 for file bool 1
      void *fb2 = fgets(file_2_stream,MAXLINESIZE,file_2) ; //fb2 for file bool 2
      if ( fb1 == NULL || fb2 == NULL ) {
       break ;
       }
    Mais le résultat est le même: la boucle for sans break en fonction de ( (int) len == lcc+1 ) ne fonctionne pas non plus.

    Se pose la question suivante: est-ce-que les tableaux file_1_stream et file_2_stream sont bourrer de données aléatoires après ce que contient la ligne du fichier ou comme je suppose savoir remplis de '\0' jusqu'à la fin du tableau...?
    Ce qui nous amène a Zephyr33:
    Ton problème ne venait pas de l'ouverture des fichiers, mais ce que tu en faisais.
    Comment faire pour que le stream ne soit pas bourré de données aléatoires ou de zéro à la fin ?
    petite remarque a Zephyr33: Tu n'a pas saisis tout a fait mon code car il y a une erreur de traitement dans ton code, je m'explique mon programme teste les longueurs de chaines et si elle sont égales, teste char après char et tu a dans ton code omis ce test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ((strlen(file_1_stream) == strlen(file_2_stream)))
            lcr++;
    Merci beaucoup pour vos réponses.
    Je retiens de cette leçon mon erreur de syntaxe ridicule: je ferai plus attention.
    Et si j'ai besoin de comparer deux chaines je ferai un test sur le '\0' terminal.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  8. #8
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Se pose la question suivante: est-ce-que les tableaux file_1_stream et file_2_stream sont bourrer de données aléatoires après ce que contient la ligne du fichier ou comme je suppose savoir remplis de '\0' jusqu'à la fin du tableau...?
    Initialement, leur contenu n'est pas déterminé. Ensuite, ils contiennent la ligne lue, le reste des lignes lues précédemment si elles étaient plus grandes puis les données initiales indéterminées qui n'ont pas été effacées par les lignes lues avant. Mais cela n'a pas d'importance.

    Ton programme est bien compliqué et se disperse. Quelque chose comme ceci devrait faire l'affaire :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define MAXLINESIZE 255
     
    int main(int argc, char *argv[]) {
      FILE *file_1 ;
      FILE *file_2 ;
      char file_1_stream[MAXLINESIZE] ;
      char file_2_stream[MAXLINESIZE] ;
      int lcr = 0 ; // for line check right
      int lcw = 0 ; // for line check wrong
      if (argc != 3) {
        printf("usage: %s",argv[0]) ;
        return EXIT_FAILURE ;
      }
      else {
        file_1=fopen(argv[1],"r") ;
        if ( file_1 == NULL ) {
          printf("unable to open file: %s",argv[1]) ;
          return EXIT_FAILURE ;
        }
        file_2=fopen(argv[2],"r") ;
        if ( file_2 == NULL ) {
          printf("unable to open file: %s",argv[2]) ;
          fclose(file_1);
          return EXIT_FAILURE ;
        }
      }
      while (fgets(file_1_stream,MAXLINESIZE,file_1)!= NULL  &&  fgets(file_2_stream,MAXLINESIZE,file_2)!= NULL) {
        int lcc;
        for ( lcc=0 ; file_1_stream[lcc] == file_2_stream[lcc] && file_1_stream[lcc]!='\0'; lcc++) {}
        if(file_1_stream[lcc] == file_2_stream[lcc])lcr++;
        else lcw++;
      }
      printf("diff %s %s\nlines equal: %i\nlines wrong: %i\n",argv[1],argv[2],lcr,lcw) ;
      return EXIT_SUCCESS;
    }
    La boucle while pouvant se simplifier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      while (fgets(file_1_stream,MAXLINESIZE,file_1)!= NULL  &&  fgets(file_2_stream,MAXLINESIZE,file_2)!= NULL) {
        if(strcmp(file_1_stream,file_2_stream)==0) lcr++;
        else lcw++;
      }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

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

Discussions similaires

  1. [WD17] Table relier deux fichiers de données
    Par v95kp5s dans le forum WinDev
    Réponses: 8
    Dernier message: 13/05/2014, 12h12
  2. Réponses: 4
    Dernier message: 10/03/2008, 16h12
  3. [windev 5.5] Recupérer les données de deux fichiers
    Par nemosfib dans le forum WinDev
    Réponses: 3
    Dernier message: 27/07/2007, 07h21
  4. Bloc corrompu dans un fichier de données !
    Par zestrellita dans le forum Oracle
    Réponses: 14
    Dernier message: 28/11/2005, 17h34

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