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 :

Suppression d'une partie d'un fichier texte


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Par défaut Suppression d'une partie d'un fichier texte
    Bonjour,

    svp j'ai bien besoin de savoir si je peux accéder à un fichier.txt pour supprimer une partie? si oui, merci de bien vouloir m'aider

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Août 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 179
    Par défaut
    Citation Envoyé par bougharmenetakoua Voir le message
    svp j'ai bien besoin de savoir si je peux accéder à un fichier.txt pour supprimer une partie?
    Bonjour,

    A priori ce n'est pas possible, il faut créer un fichier temporaire (ouvert en écriture) y mettre la partie de ton fichier d'origine (ouvert en lecture) que tu souhaites conserver puis effacer le fichier d'origine et renommer le fichier temporaire.

    Pour la manipulation des fichiers :
    http://melem.developpez.com/tutoriel...rs/?page=cours

  3. #3
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 10
    Par défaut
    Bonjour,

    Comme l'a souligné pythéas, il faut créer un fichier temporaire.

    J'ai trouvé ce 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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    #include <stdio.h>
    #include <windows.h>
    // Taille du buffer de lecture
    #define ONEMEGA 0x100000
    //Permet de supprimer la chaine String du fichier FileName
    DWORD deleteStringInFile(char *FileName, char *String);
    int main(int argc, char **argv)
    {
    // Test des paramètres
        if (argc != 3) {
    	printf("Problem when calling the applicationn");
    	printf("Exemble: exe test.txt coucou2n");
    	system("pause");
    	return -1;
        }
    // Appel à la fonction
        DWORD result = deleteStringInFile(argv[1], argv[2]);
        printf("%sn", (result == 0) ? "pas trouvé" : "trouvé");
        system("pause");
        return 0;
    }
     
    DWORD deleteStringInFile(char *FileName, char *String)
    {
        char *buffer;		// Buffer de lecture
        char *c, *pout;		// Délimiteurs
        unsigned int i, lenfind = strlen(String);
        DWORD dwread, dwritten, bfound = 0;
    // Ouverture d'un fichier temporaire
        HANDLE htemp = CreateFile("temp.txt", GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_FLAG_SEQUENTIAL_SCAN, 0);
        if (htemp == INVALID_HANDLE_VALUE)
    	return 0;
    // Ouverture du fichier en mode lecture
        HANDLE hfile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
        if (hfile == INVALID_HANDLE_VALUE)
    	return 0;
    // Allocation du buffer dans le tas
    // sinon, stack overflow surement
        buffer = (char *) HeapAlloc(GetProcessHeap(), 0, ONEMEGA);
      fromFL:
    // Remplissage du buffer
        dwread = 0;
        ReadFile(hfile, buffer, ONEMEGA, &dwread, 0);
        if (bfound) {
    // Si la chaine a été trouvée, on se contente d'écrire
    // et on quitte si on a lu moins d'un Mo
    	WriteFile(htemp, buffer, dwread, &dwritten, 0);
    	if (dwread != ONEMEGA)
    	    goto closeFL;
    	else
    	    goto fromFL;
        }
    // Si le nombre de caractères lus < taille de String alors exit
        if (dwread < lenfind)
    	goto closeFL;
    // Init des délimiteurs
        pout = buffer + dwread - lenfind;
        c = buffer;
      firstcar:			// test du 1er caractère
        while (*c != String[0]) {
    // Test s'il reste assez de caractères
    	if (++c >= pout) {
    	    if (dwread != ONEMEGA)
    		goto closeFL;
    	    WriteFile(htemp, buffer, dwread, &dwritten, 0);
    	    goto fromFL;
    	}
        }
        for (i = 1; i < lenfind; i++) {
    	if (c[i] != String[i])
    	    goto notfound;
        }
    // OK! Chaine trouvée!
        bfound = 1;
        WriteFile(htemp, buffer, c - buffer, &dwritten, 0);
        WriteFile(htemp, c + lenfind, pout - c, &dwritten, 0);
        goto fromFL;
      notfound:
    // KO, pas trouvée :(
    // s'il reste assez de caractères, on continue avec le même buffer
        if (++c < pout)
    	goto firstcar;
        if (dwread == ONEMEGA) {
    // sinon, lecture d'un nouveau buffer
    	WriteFile(htemp, buffer, dwread, &dwritten, 0);
    	goto fromFL;
        }
      closeFL:
    // Fermeture des fichiers
        CloseHandle(hfile);
        CloseHandle(htemp);
    // Si la chaine a été trouvée, on ré-écrit le fichier
        if (bfound)
    	CopyFile("temp.txt", FileName, false);
    // Destruction du fichier temporaire
        DeleteFile("temp.txt");
    // Désallocation du buffer
        HeapFree(GetProcessHeap(), 0, buffer);
    // Fin
        return bfound;
    }
    Source : cppfrance.

    Je n'ai pas testé, mais ça pourrait peut être t'aider .

  4. #4
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Bonjour,

    Citation Envoyé par pythéas
    A priori ce n'est pas possible, il faut créer un fichier temporaire ...
    Citation Envoyé par mirecalu
    Comme l'a souligné pythéas, il faut créer un fichier temporaire.
    Si le passage par un fichier temporaire est très souvent utilisé et convient généralement bien, il n'y a pas d'impossibilité technique à aller supprimer une partie d'un fichier (texte ou binaire) sans passer par un fichier temporaire.

    Attention, il n'y a pas de recette miracle : "aller supprimer une partie du fichier", c'est écrire, à la place de ce que l'on veut supprimer, ce qui vient après, c'est-à-dire "boucher les trous".

    Je ne dis pas que cette technique est à utiliser à tout bout de champs mais, dans certains cas, elle peut être plus efficace que de réécrire quasiment tout le fichier, sauf quelques "trucs", dans un fichier temporaire (cas de très gros fichiers, avec des choses à enlever qui se situent "plutôt" vers la fin du fichier).

    Il suffit pour ça :
    • d'ouvrir le fichier en mode mise à jour "r+"
    • de gérer deux positions courantes, une en lecture, une en écriture
    • de bien se repositionner explicitement (via fseek) quand on passe d'une lecture à une écriture, ou l'inverse
    • de tronquer (quand il s'agit d'une suppression, pas le choix) le fichier.



    Mise en application sur un cas simple (qui ne justifie absolument pas d'utiliser cette méthode mais c'est pour l'exemple).

    suppression des lignes de numéros pairs d'un fichier texte (ma première ligne a le numéro 1)

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    #define TAILLE_JAMAIS_ATTEINTE  128
     
    int main(int argc,char *argv[])
    {
        FILE *fp;
        char  buffer[TAILLE_JAMAIS_ATTEINTE];
        int   noligne = 0;
        long  position_lecture  = 0L;
        long  position_ecriture = 0L;
     
        fp = fopen(argv[1],"r+");
     
        while(fgets(buffer,TAILLE_JAMAIS_ATTEINTE,fp))
        {
            noligne += 1;
     
            // j'ai avance en lecture - je memorise la nouvelle position
            position_lecture = ftell(fp);
     
            if (noligne % 2)
            {
                // positionnement au bon endroit pour ecrire
                fseek(fp,position_ecriture,SEEK_SET);
                // ecriture
                fputs((const char *)buffer,fp);
                // memorisation de la position d'ecriture
                position_ecriture = ftell(fp);
                // repositionnement a la position de lecture pour le fgets qui suit
                fseek(fp,position_lecture,SEEK_SET);
            }
        }
     
        fclose(fp);
     
        // on tronque le fichier a sa "vraie" taille
        // Sous Windows, j'ai cru comprendre qu'on peut utiliser SetEndOfFile
        // sous Unix/Linux, on utilise truncate :
        truncate(argv[1],(off_t)position_ecriture);
     
        return 0;
    }
    Appliqué au fichier source ci-dessus :

    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
    plx@sony:~$ ./supprime_lignes_paires supprime_lignes_paires.c
    plx@sony:~$ 
    plx@sony:~$ more supprime_lignes_paires.c
    #include <stdio.h>
    #include <unistd.h>
    #define TAILLE_JAMAIS_ATTEINTE  128
    int main(int argc,char *argv[])
        FILE *fp;
        int   noligne = 0;
        long  position_ecriture = 0L;
        fp = fopen(argv[1],"r+");
        while(fgets(buffer,TAILLE_JAMAIS_ATTEINTE,fp))
            noligne += 1;
            // j'ai avance en lecture - je memorise la nouvelle position
     
            {
                fseek(fp,position_ecriture,SEEK_SET);
                fputs((const char *)buffer,fp);
                position_ecriture = ftell(fp);
                fseek(fp,position_lecture,SEEK_SET);
        }
        fclose(fp);
        // on tronque le fichier a sa "vraie" taille
        // sous Unix/Linux, on utilise truncate :
     
    }
    plx@sony:~$
    C'est sur que, maintenant, même s'il passait à la compilation, il marcherait beaucoup moins bien ...

  5. #5
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Citation Envoyé par plxpy
    Si le passage par un fichier temporaire est très souvent utilisé et convient généralement bien, il n'y a pas d'impossibilité technique à aller supprimer une partie d'un fichier (texte ou binaire) sans passer par un fichier temporaire.
    Mais cela demande d'utiliser des fonctions spécifiques au système (par exemple SetEndOfFile sous Windows). En d'autres termes, ce n'est pas portable. La seule façon portable d'arriver au résultat est d'utiliser un fichier temporaire.

    Citation Envoyé par plxpy
    dans certains cas, elle peut être plus efficace que de réécrire quasiment tout le fichier
    Et j'ajoute qu'elle est toujours au moins aussi efficace que la façon fichier temporaire.

    @mirecalu: C'est dommage d'utiliser des fonctions spécifiques à Windows pour implémenter un algorithme qu'on aurait pu écrire en C standard.

  6. #6
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 10
    Par défaut
    Citation Envoyé par Melem Voir le message
    @mirecalu: C'est dommage d'utiliser des fonctions spécifiques à Windows pour implémenter un algorithme qu'on aurait pu écrire en C standard.
    Je suis tout à fait d'accord avec toi. Après, ça dépend de ses besoins, s'il compte juste l'utiliser sur Windows je pense que ce code est largement suffisant.

Discussions similaires

  1. Récupérer une partie d'un fichier texte
    Par Ladgalen dans le forum Fortran
    Réponses: 2
    Dernier message: 17/05/2008, 17h43
  2. copier une partie d'un fichier texte dans un autre
    Par Valarauko dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 23/10/2007, 21h17
  3. extraire une partie d'un fichier texte
    Par Mydriaze dans le forum Langage
    Réponses: 5
    Dernier message: 15/06/2007, 12h46
  4. Réponses: 4
    Dernier message: 24/11/2006, 17h03
  5. [VB]recherche dans une partie d'un fichier texte
    Par malhivertman1 dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 19/01/2006, 11h56

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