[C] Ecrire au milieu d'un fichier

a marqué ce sujet comme résolu.

Bonjour,

J’ai un fichier .txt dans lequel il y a un mot par ligne. J’aimerais écrire une fonction qui prend en paramètre un mot char* word, qui le cherche dans le fichier et si le mot est trouvé on écrit trouvé juste en dessous et le fichier continue. Par exemple si le .txt c’est :

abricot
bonjour
salut
bonjour

et que ma fonction prend en paramètre le mot bonjour alors j’obtiens le .txt suivant :

abricot
bonjour
trouvé
salut
bonjour
trouvé

Pour le moment j’ai fais une fonction qui cherche un mot le trouve et écris trouvé ça me donne ça :

void findW (char* word){
    FILE* file = fopen("file.txt", "r+");
    char line[1000] = "";
    
    if(file != NULL){
        while(fgets(line, 1000, file) != NULL){
            if (strcmp(line, word) == 0 || strcmp(f(line), word) == 0{ \\f enlève le caractère \n 
                fputs("\ntrouvé\n", file);
            }
        }
    }
    fclose(file);
}

Le problème c’est que ce code ne marche pas… fputs écrit à la fin du fichier et pas juste en dessous du premier bonjour ? Ensuite comment faire pour garder les mots qui ne sont pas des bonjour ?

Merci beaucoup.

+0 -0

Bonjour,

Le problème c’est que ce code ne marche pas… fputs écrit à la fin du fichier et pas juste en dessous du premier bonjour ? Ensuite comment faire pour garder les mots qui ne sont pas des bonjour ?

Je ne pense pas que fputs fasse ça. fputs écrit là où tu es dans le fichier. Il n’écrit pas à la fin. Comme tu es en plein milieu du fichier, il va réécrire sur le fichier. Ça ne donnera rien de bon.

Ce que tu dois faire, c’est utiliser un fichier temporaire ou une structure quelconque pour sauvegarder ce que tu as déjà lu.

Par exemple en utilisant la fonction tmpfile qui crée un fichier temporaire.

    FILE* file = fopen("file.txt", "r+");
    FILE* tmpF = tmpfile();
    char line[1000] = "";

    if(file != NULL && tmpF != NULL ) {

Puis en copiant le contenu du fichier temporaire dans le nouveau fichier :

        rewind(file);
        rewind(tmpF);

        int c = 0;
        while((c = fgetc(tmpF)) != EOF) {
            fputc(c, file);
        }
+1 -0

Merci beaucoup pour vos réponses.

Je ne pense pas que fputs fasse ça. fputs écrit là où tu es dans le fichier. Il n’écrit pas à la fin. Comme tu es en plein milieu du fichier, il va réécrire sur le fichier. Ça ne donnera rien de bon.

Pourtant lorsque je test mon code sur le fichier :

abricot 
bonjour 
salut

j’obtiens :

abricot
bonjour
salut
trouvé

du coup je ne comprends pas trop ce que fais la fonction fputs.

Je vais essayer de faire comme tu as dis du coup :) Merci beaucoup !

+0 -0

En faisant une recherche sur le mot « salut » ? Si oui c’est normal, le curseur se trouve alors à la fin du fichier (puisque c’est le dernier mot) et tout se passe bien.

Mais pour un mot en milieu de fichier, ça aurait pour effet d’écraser ce qui suit.

Salut,

du coup je ne comprends pas trop ce que fais la fonction fputs.

CFile

Utiliser un flux en lecture et écriture (r+, w+ ou a+) induis un certain nombre de restrictions. Elles sont expliquées dans ce chapitre du tuto C.

Si vous utilisez un tel flux, vous devez appeler une fonction de déplacement entre deux opérations de natures différentes ou utiliser la fonction fflush() entre une opération d’écriture et de lecture. Si vous ne souhaitez pas vous déplacer, vous pouvez utiliser l’appel fseek(flux, 0L, SEEK_CUR) afin de respecter cette condition sans réellement effectuer un déplacement.

Ceci explique le comportement que tu obtiens. Si tu essayes le code ci-dessous, tu verras que « trouvé » est bien écrit après « abricot » (mais a également remplacé le premier « bonjour »).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


static void
chomp(char *s)
{
    while (*s != '\n' && *s != '\0')
        ++s;

    *s = '\0';
}


int
main(void)
{
    char buf[255];
    FILE *fp = fopen("file.txt", "r+");

    if (fp == NULL) {
        perror("fopen");
        return EXIT_FAILURE;
    }

    while (fgets(buf, sizeof buf, fp) != NULL) {
        chomp(buf);

        if (strcmp(buf, "abricot") == 0) {
            if (fseek(fp, 0L, SEEK_CUR) < 0) {
                perror("fseek");
                return EXIT_FAILURE;
            }
            if (fputs("trouvé\n", fp) == EOF) {
                perror("fputs");
                return EXIT_FAILURE;
            }
            if (fseek(fp, 0L, SEEK_CUR) < 0) {
                perror("fseek");
                return EXIT_FAILURE;
            }
        }
    }

    if (fclose(fp) == EOF) {
        perror("fclose");
        return EXIT_FAILURE;
    }
    return 0;
}

Pour le reste, comme cela a été dit, un fichier doit être vu comme une bande magnétique : il n’est pas possible d’insérer des données, si tu écris à un point donné tu remplaces ce qu’il y a à cet endroit.

+0 -0

Bonjour,

Un truc comme çà devrait fonctionner :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char ligne[512];
    FILE *fSrc = fopen("src.txt", "r");
    FILE *fDest = fopen("dest.txt", "w");

    if (fSrc == NULL) {
        perror("fopen");
        return EXIT_FAILURE;
    }

    if (fDest == NULL) {
        perror("fopen");
        return EXIT_FAILURE;
    }

    while (fgets(ligne, sizeof ligne, fSrc) != NULL) {
        fputs(ligne, fDest);
        if (strcmp(ligne, "bonjour\n") == 0) {
            fputs("trouvé\n", fDest);
        }
    }

    if ( (fclose(fSrc))|| fclose(fDest) == EOF) {
        perror("fclose");
        return EXIT_FAILURE;
    }
    return 0;
}

Ton code devrait marché en gros.

Par-contre, les erreurs ne sont pas très bien gérées. Si par exemple fopen("dest.txt", "w") échoue, alors fSrc ne sera pas fermé. Le contraire si fclose(fSrc) échoue.

M’enfin c’est quasiment rien. Par-coontre, le plus curieux est quand même cette ligne :

    if ( (fclose(fSrc))|| fclose(fDest) == EOF) {

Tu ne peux pas vraiment faire ça en C. Tu dois plutôt faire :

    if ( fclose(fSrc) == EOF || fclose(fDest) == EOF) {

Tu ne peux pas factoriser.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte