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 :

Modifier une chaine de caractère dans un fichier texte


Sujet :

C

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 151
    Points : 87
    Points
    87
    Par défaut Modifier une chaine de caractère dans un fichier texte
    Bonjour

    J'ai un problème simple, mais je ne sais pas trop comment m'y prendre.

    J'ai un fichier .txt avec une chaine de caractère récurrente que j'aimerais remplacer par une autre chaine de caractère.

    En gros, admettons que dans un fichier .txt où y'a plein de truc d'écrit, y'a la chaine "toto" qui revient souvent, et j'aimerais remplacer tous ces toto par des "newChaine", vous voyez l'truc ?

    Bien entendu le plus compliqué n'est pas vraiment de remplacer la chaine, mais plutôt de récuperer puis réenregistré dans le ficher .txt

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Points : 13
    Points
    13
    Par défaut
    Bonsoir.

    En fait tu ne remplaces pas la chaine dans le fichier original, tu crées un nouveau fichier dans lequel tu recopies le premier fichier avec les chaines modifiées. Tu supprimes le premier fichier et tu renommes le nouveau avec le nom de l'ancien.

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 151
    Points : 87
    Points
    87
    Par défaut
    Oui, si tu veux, mais ca encore c'est un détail. La question c'est comment je fais ?

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Je n'ai pas beaucoup réfléchit, mais si tu lisais ton fichier octet par octet et que tu stocke tout dans une liste doublement chaînée de caractère et qu'ensuite tu parcours ta chaîne et dès que tu rencontre le premier caractère de ton mot cherché, tu :
    - stocke le pointeur sur le maillon
    - tu lis caractère par caractère voir si ceci correspond à ta chaîne
    - si oui, tu remplace très facilement la chaîne
    - si non, tu reviens à ton maillon grâce au pointeur préalablement enregistré et tu continus.

    Exemple :
    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
     
    char chaîne[max];
    int i = 0;
    while(i != max)
    {
               if( maillon && chaine[i] == maillon->c)
               {
                         maillon = maillon->suivant;
                          i++;
               }
                else
                          return NULL;
     
    }
    return maillon;
    Donc si cette fonction retourne NULL, tu continus.
    Sinon tu supprime de ton maillon courant au maillon retourné puis tu insère la nouvelle chaine de caractère.

  5. #5
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Salut,

    Peut-être en utilisant simplement un tableau de caractère ça pourrait le faire. Tu stockes ton fichier dans un premier tableau de char. Tu alloues un deuxième tableau au moins de la taille du premier.

    L'algorithme naif, et le plus simple, c'est de parcourir le premier tableau et pour chaque caractère, tu regardes si la suite correspond à la chaine que tu veux remplacer. Si non tu écris le caractère et tu avances de 1, si oui tu écris ton nouveau mot et tu avances de la taille de l'ancien mot dans le premier tableau.

    Cet algo n'est peut-être pas tout à fait juste, je ne l'ai pas testé ! C'est pour te donner une idée d'implémentation.
    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
    int main()
    {
      char* tab1 = malloc(taille_du_fichier); // voir la faq C pour récupérer la taille du fichier.
     
      char* tab2 = malloc(taille_du_fichier);
     
      for(int i=0, j=0; i < taille_du_fichier;)
      {
         int match = 1, k;
         for(k= 0; k < taille_mot_a_rechercher && match && (i+k) < taille_du_fichier; ++k)
           match = tab1[i + k] == mot_a_rechercher[k];
     
        // Attention au dépassement de buffer de tab2, il faut que tu ré-alloues si besoin !! (C'est seulement possible si la chaine à remplacer est plus courte que la nouvelle chaine).
        if(match && k == taille_mot_a_rechercher)
        {
           for(k = 0; k < taille_mot_remplacant; ++k)
             tab2[j+k] = mot_remplacant[i+k];
           j += taille_mot_remplacant;
           i += taille_mot_a_rechercher;
        }
        else
        {
           tab2[j++] = tab1[i++];
        }
      }
    }
    C'est l'algo naif car il peut être en O(n²).

    Pour la complexité spaciale (l'espace qu'occupera ton programme en mémoire vive), je n'ai pas trop d'idée d'amélioration à part ne pas copier tout le fichier en mémoire et copier seulement morceaux par morceaux.

    Par contre, pour la complexité temporelle, tu peux tenter d'implémenter l'algorithme de recherche de pattern de KMP, regarde sur internet, il est plus performant.

    Bonne chance

  6. #6
    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
    L'inconvénient, est qu'il n'y a aucun moyen de déterminer la taille à choisir pour le tableau 2 si la chaine de remplacement est plus longue que la chaine à remplacer.

    J'envisagerai plutôt de le faire fichier à fichier :
    T, un tableau contenant la chaine à remplacer comportant N caractères.
    ix, un index sur ce tableau
    - ix =0
    - Faire :
          - lire le caractère suivant du fichier source
          - Si la fin de fichier n'est pas atteinte :
               - Si le caractère lu n'est pas égal à T[ix] :
                     - copier les éléments de T de 0 à ix-1 ; mettre ix à 0
               - Si le caractère lu est égal à T[ix] :
                     - incrémenter ix. 
                     - Si ix == N :
                          - copier la chaine de remplacement ;  mettre ix à 0      
               - Sinon :  
                     - copier le caractère       
      Tant que la fin de fichier n'est pas atteinte
    - Copier les éléments de T de 0 à ix-1
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  7. #7
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 151
    Points : 87
    Points
    87
    Par défaut
    Je vous remercie tous pour vos réponse

    J'ai pas encore eu le temps de tester. Mais je me rend compte en tout cas que finalement mon "problème" n'était pas si simple que ça. ^^

    Neckara>> Je suis un débutant en C++ donc j'ai un peu de mal à suivre avec ton histoire de maillon. Et tu ne traite que la sous-fonction, pas la gestion de fichier .txt (c'est déjà pas mal hein )

    Trademark>>
    C'est l'algo naif car il peut être en O(n²)
    Gné ?
    Cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    match = tab1[i + k] == mot_a_rechercher[k];
    permet de mettre la valeur du tableau dans match si tab1[i + k] == mot_a_rechercher[k], c'est ça ?
    Et la chaine à remplacer est bien plus courte que celle à rechercher
    Après j'suis pas sur de ce que fera ce code, mais ça parait pas mal. A voir.
    Et pareil que Neckara, je ne sais toujours pas comment ouvrir et sauvegarder mon fichier .txt.

    diogene>> Donc du coup pas de souci vu que ma chaine à remplacer est plus courte que l'ancienne.
    Comment tester que la fin du fichier n'est pas atteinte ? (j'ai pas l'habitude de gérer des fichier >.<')


    J'ai pas encore eu le temps de tester, mais je vous tiens au courant de mes essais.

    Ah et puis aussi, je précise: Je pense que c'est plus simple de sauvegarder dans un nouveau fichier plutôt que d'écraser l'ancien. Et ca permet aussi si le code fait n'importe quoi de ne pas écraser mon ancien fichier ^^

  8. #8
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Pour les listes, regarde du côté de std::list.

    Pour lire/écrire dans un fichier, regarde du côté de fstream.

    Si tu veux écrire dans un nouveau fichier, l'algorithme est assez simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Tu lis ton fichier caractère par caractère
    - Si le caractère lu est le premier de ta chaîne recherchée :
              - tu met le caractère dans une file (Trademark devrait pouvoir te dire quel est le conteneur approprié pour ce cas là)
             - Tant que le caractère lu correspond au caractère attendu :
                         - tu met le caractère dans la file
             - Si tu arrive à la fin de ta chaîne, tu met ta nouvelle chaine dans ton fichier
             - Sinon tu recommence avec ta file au lieu d'utiliser le flux.
    - Sinon tu met le caractère dans ton nouveau fichier.
    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
     
    int i = 0;
    char c;
    char * chaine = ...;
    char * remplacer = ...;
    while(fluxLecture >> c)
    {
            if(! i && c != chaine[i])
                    fluxEcriture << c;
            else if (c == chaine[i])
            {
                    file.push_back(c);
                    ++i;
                    if(! chaine[i])
                    {
                               fluxEcriture << remplacer;
                               i = 0;
                               //vider la file
                     }
             }
            else
            {
                     i = 0;
                     //on met le premier élément de la file dans le FluxEcriture
                     //tant qu'on ne trouve pas chaine[0], on lit un élément dans la file et on le place dans FluxEcriture
                    //fin tant que
                    //s'il reste des éléments dans la file, on créé une nouvelle file
                    //tant qu'on arrive pas au bout de la première file, on lit un élément.
                             //si l'élément correspond à chaine[i], on le met dans la deuxième file
                             //sinon on vide la nouvelle file.
                    //etc... 
             }
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    match = tab1[i + k] == mot_a_rechercher[k];
    match = true si tab1[i + k] == mot_a_rechercher[k];match = false sinon

  9. #9
    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
    @Neckara
    Pour les listes, regarde du côté de std::list.

    Pour lire/écrire dans un fichier, regarde du côté de fstream.
    On est en C, pas en C++ !
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  10. #10
    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
    Comment tester que la fin du fichier n'est pas atteinte ? (j'ai pas l'habitude de gérer des fichier >.<')
    La fonction de lecture sur le fichier renvoie une valeur qui permet de savoir si la fin de fichier est atteinte (ou si une erreur s'est produite).
    Par exemple, avec fgetc()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int c;
    while( (c=fgetc(..)) != EOF)
    {
       unsigned char carac  = c;   
      //   Utiliser le caractère lu carac  
     }
    // si on veut distinguer ici entre une fin de fichier ou une erreur,
    // utiliser feof() et ferror()
    fclose(..);
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  11. #11
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par diogene Voir le message
    @Neckara


    On est en C, pas en C++ !
    Oups, à force de passer du forum C au forum C++ ...

    Donc pour la lecture, écriture, il faut utiliser fopen.
    Pour les listes, il faut les programmer toi-même.

    Après tu as différentes architectures pour une liste.
    En utilisant la fonction de recherche (tout en haut à droite), tu devrais pouvoir trouver un tutoriel sur les listes.


    EDIT :
    Je suis un débutant en C++
    Si le PO m'induit en erreur aussi...

  12. #12
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 151
    Points : 87
    Points
    87
    Par défaut
    Ben à l'origine je programme en C, mais j'ai remarqué que c'était du C++, c'est pour ça que j'ai dit ça.

    Et merci pour vos aide. J'apprends beaucoup. Je vais essayer de faire quelque chose. Mais c'est pas dit que j'y arrive...

  13. #13
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Ben à l'origine je programme en C, mais j'ai remarqué que c'était du C++, c'est pour ça que j'ai dit ça.
    Il faut savoir, c'est soit du C++, soit du C. La technique sera complétement différente de l'un à l'autre, il ne faut pas tout confondre, ce sont deux langages bien distincts même si l'un est inclus dans l'autre.

Discussions similaires

  1. [Batch] extraction caractère d'une chaine de caractère dans un fichier texte
    Par Zoïïc dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 24/06/2014, 19h20
  2. Récupérer une chaine de caractères dans un fichier texte
    Par neutrall dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 31/05/2011, 00h37
  3. Réponses: 1
    Dernier message: 05/11/2009, 15h19
  4. Remplacer une chaine de caractère dans un fichier texte.
    Par Empty_body dans le forum VBA Access
    Réponses: 1
    Dernier message: 19/01/2008, 11h16
  5. Réponses: 3
    Dernier message: 25/07/2006, 08h40

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