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 :

Concaténation fichiers


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 18
    Par défaut Concaténation fichiers
    Bonjour,

    Je souhaite ouvrir plusieurs fichiers txt afin de concaténer leurs données (et en les modifiant un petit peu - changement et ajout de caractères) dans un même fichier. Mon programme de lecture+modification fonctionne sans problème lorsque je ne lis qu'un fichier, mais lorsque j'en lis plusieurs, la lecture se termine par un "segmentation fault".
    Voici le code:

    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
    #include <string.h>
    #include <stdio.h>
    #include <dirent.h>
    #include <stdlib.h>
     
    int main(void)
    {
      char *suiteChaine;
      int cpt=0;
      int tpc=0;
      DIR * rep = opendir("/home/mehdi/essai");
     
      if (rep != NULL)
        {
          struct dirent * ent;
     
          while ((ent = readdir(rep)) != NULL)
    	{
    	  cpt++;
    	  suiteChaine = strstr(ent->d_name,"Vloc_Rloc");
    	  if (suiteChaine != NULL)
    	    {
    	      tpc++;
    	    }
     
    	}
     
          closedir(rep);
        }
     
      int i;
      char fname[100];
      FILE* suite=fopen("finish.dat","w");
     
      for (i=1;i<=tpc;i++)
        {
          sprintf(fname,"/home/mehdi/essai/Vloc_Rloc.OUT.%d",i);
          FILE* vlocrloc=fopen(fname,"r");
          FILE* traitement=fopen("essai.dat","w+");  
     
          int c_lu;
          int c_ecrit;
          int last=0;
     
          while ((c_lu = fgetc(vlocrloc)) != EOF)
    	{
    	  c_ecrit = c_lu;
    	  if (c_lu == '!')
    	    {
    	      c_ecrit = ' ';
    	    }
    	  else
    	    if (c_lu == '=')
    	      {
    		c_ecrit = ' ';
    	      }
    	    else
    	      if (c_lu == '-')
    		{
    		  if(last == 'H') 
    		    {
    		      putchar(' ');
    		      putc(' ',traitement);
    		    } 
    		}
    	      else    
    		if (c_lu == 'D')
    		  {
    		    c_ecrit = 'e';
    		  }
    	  putchar(c_ecrit);
    	  putc(c_ecrit,traitement);
    	  last = c_lu;
    	}
     
          fclose(vlocrloc);      
          fclose(traitement);
     
        }
     
      fclose(suite);
      return 0;  
    }
    Explication: La première partie permet de compter le nombre de fichiers Vloc_Rloc.OUT dans mon répertoire essai/.
    Ensuite, je lis+modifie les fichiers Vloc_Rloc.OUT.x un par un, et je les écris chacun à leur tour dans le fichier traitement.

    Qu'en pensez vous? Est-ce que je dois plutôt tous les lire et les modifier avant d'écrire?

    PS: il me semble que le putchar ne rencontre pas de problème, puisque le message segmentation fault apparaît après l'écriture dans le flux de sortie standard (la lecture et la modification apparaissent bien sur mon terminal). L'origine serait donc plutôt le putc, donc l'écriture dans traitement.

  2. #2
    Membre Expert
    Avatar de muad'dib
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2003
    Messages : 1 013
    Par défaut
    Petite question : il te sert à quoi le pointeur sur FILE* suite ?

    De plus tu ne testes jamais si l'ouverture de tes fichiers a fonctionné
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    FILE* f = fopen(..);
    if(f != NULL) { ... }
    Ça enlèvera des bugs potentiels.

    Je peux pas beaucoup plus t'aider j'ai pas de compilateur C à disposition.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 18
    Par défaut
    Bonjour muad' dib,

    J'ai oublié d'enlever le FILE *suite! En fait, après avoir écrit mes données dans mon fichier "traitement" (si j'y parviens!), je les lis (avec un scanf) pour ensuite ne sélectionner que certaines informations qui seront écrites dans mon fichier "suite".
    Je vais rajouter de ce pas le test d'ouverture des fichiers.

    Relance...

  4. #4
    Expert confirmé
    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
    Par défaut
    Le déroulement suivant semble plus logique :
    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
    int main(void)
    {
    ....
      FILE* traitement=fopen("essai.dat","w");
      if(traitement != NULL)
      {
        for (i=1;i<=tpc;i++)
        {
          ....
          FILE * vlocrloc=fopen(fname,"r");
          if(vlocrloc != NULL)
          {
             while ((c_lu = fgetc(vlocrloc)) != EOF)
             {
                ....
             }
             fclose(vlocrloc);
          }
        }
        fclose(traitement);
      }
      return 0;
    }
    Remplace tous ces if else par un switch, tu gagneras en lisibilité.

  5. #5
    Membre confirmé Avatar de ironzorg
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 288
    Par défaut
    Pourquoi ne pas faire un script ?

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 18
    Par défaut
    OK merci du conseil Diogène.

    Mon problème est résolu.
    En fait, j'ai compté le nombre de fichiers Vloc_Rloc présent dans mon répertoire, et celui-ci ne correspondait pas au nombre de fichiers bien présent quand je parcourais le répertoire essai en question. Le segmentation fault venait de ça.
    Mais pourquoi comptait il plus de fichiers qu'il y en avait?? J'ai alors fait un ls dans mon terminal pour voir avec stupeur qu'il y avait en plus de ceux affichés dans l'explorateur les fichiers Vloc_Rloc.OUT.x~. J'ai alors supprimé les fichiers~, et tout fonctionne à présent.

    Merci pour vos conseils

    PS @ironzorg : que signifie faire un script?

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 473
    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 473
    Par défaut
    Tu sais quand même que la commande cat signifie catenate et sert en principe à faire ce que tu veux faire, j'espère :

    $ cat fichier1 fichier2 fichier3 > fichierfinal

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 18
    Par défaut
    La commande cat dans le terminal? Le problème, c'est que j'ai au minimum 80000 fichiers txt à concaténer dans un même fichier, donc l'usage du terminal dans mon cas est plutot limité.
    La commande cat dans mon programme en c : je ne souhaite pas concaténer tous mes fichiers puis modifier mon fichier final, mais plutot modifier mes fichiers et les réécrire un à un.

  9. #9
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 473
    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 473
    Par défaut
    Citation Envoyé par sayanmehdi Voir le message
    La commande cat dans le terminal? Le problème, c'est que j'ai au minimum 80000 fichiers txt à concaténer dans un même fichier, donc l'usage du terminal dans mon cas est plutot limité.
    Au contraire, c'est à cela qu'il sert.

    C'est nettement moins pénible de faire cela en Shell qu'en C. Un terminal UNIX n'a rien de comparable à un boîte D.O.S.

    La commande cat dans mon programme en c : je ne souhaite pas concaténer tous mes fichiers puis modifier mon fichier final, mais plutot modifier mes fichiers et les réécrire un à un.
    Non, je ne te parle pas d'appeler cat depuis le programme en C, ce qui n'a effectivement aucun intérêt.

    Le genre de manipulations de fichiers que tu veux faire est très courant sous Unix, qui dispose par conséquent d'une palanquée d'outils pour faire cela très simplement. C'est très différent du monde Windows dans lequel tu ne disposes que de très peu d'outils par défaut.

    Par exemple, en s'inspirant d'un problème posé dans tes précédentes discussions, si tu veux retrouver tous les fichiers commençant par « Vloc_Rloc.OUT. … » dans le répertoire courant ainsi que tout ses sous-répertoires, en insérant un espace après tous les « H= » rencontrés et en stockant le résultat de la lecture et conversion de tous les fichiers dans un seul grand fichier de sortie, tu fais :

    $ find . -name 'Vloc_Rloc.OUT.*' -exec sed -e 's/H=/H= /g' {} >> fichierfinal \;

    Le fichier « fichierfinal » sera créé s'il n'existe pas déjà, tous tes fichiers « Vloc_Rloc.OUT. », aussi nombreux qu'ils soient, seront lus l'un après l'autre, et leur contenu modifié par sed ira automatiquement prendre place à la fin du fichier « fichierfinal », après ce qui s'y trouve déjà.

    Si c'est bien ce que tu cherches à faire, tout ton travail est effectué en une ligne et deux minutes de calcul.

  10. #10
    Membre confirmé Avatar de ironzorg
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 288
    Par défaut
    Au contraire, c'est à cela qu'il sert.

    C'est nettement moins pénible de faire cela en Shell qu'en C. Un terminal UNIX n'a rien de comparable à un boîte D.O.S.
    J'aurais pas mieux dit. Le shell est bien plus performant que n'importe quel programme que tu pourras faire en C (ca depend de tes perfs en programmation).

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 18
    Par défaut
    (1 mois plus tard...)

    Merci pour le conseil, l'option find par le shell est très intéressante. Je suis en train de chercher plus d'infos sur cette fontion. Peut-être savez vous ce qu'il faudrait entrer en ligne de commande pour non plus écrire dans un autre fichier mais dans le même fichier (celui qu'on lit) ??

  12. #12
    Membre confirmé Avatar de ironzorg
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 288
    Par défaut
    D'apres ce que j'ai compris c'est quelquechose comme ca qu'il te faut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat a > tmp && mv tmp a

  13. #13
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 473
    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 473
    Par défaut
    Citation Envoyé par sayanmehdi Voir le message
    Peut-être savez vous ce qu'il faudrait entrer en ligne de commande pour non plus écrire dans un autre fichier mais dans le même fichier (celui qu'on lit) ??
    Il n'y a pas de méthode universelle et garantie sur tous les UNIX. Mais si tu utilises sed pour faire tes modifs, et que tu utilises sa version GNU (formellement, sous Linux) ou BSD (paraît-il), alors tu peux mettre l'option -i (in-place) pour que les modifs soient appliquées directement à leur place dans le fichier plutôt que sur le flux renvoyé sur la sortie standard.

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 18
    Par défaut
    @ Ironzorg :
    Je ne comprends pas ce que vous avez écrit...

    @ Obsidian :
    Cela semble bien fonctionner le -i pour le sed. Je teste une dernière fois, avant de mettre résolu!

    Merci

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 18
    Par défaut
    C'est bon! J'ai ce que je recherchais.

    Merci à tous! Super communauté que celle de Développez.com!

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

Discussions similaires

  1. [Batch] Concaténation Fichiers avec suppression premieres lignes
    Par Tequilapaf dans le forum Scripts/Batch
    Réponses: 3
    Dernier message: 09/04/2009, 12h35
  2. Concaténer fichiers en Perl
    Par Arg0l dans le forum Langage
    Réponses: 4
    Dernier message: 09/03/2009, 16h10
  3. concaténation fichier video
    Par kain31 dans le forum C++
    Réponses: 3
    Dernier message: 22/03/2007, 14h50
  4. [VBA-E]Concaténer fichier texte
    Par illight dans le forum Macros et VBA Excel
    Réponses: 19
    Dernier message: 11/05/2006, 10h16
  5. concaténer fichiers texte ligne par ligne
    Par tiboleo dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 16/03/2006, 13h45

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