[langage C]remplacer chaine de caractere

[Fermé]
Signaler
-
Messages postés
1
Date d'inscription
samedi 23 octobre 2004
Statut
Membre
Dernière intervention
25 septembre 2010
-
Bonjour,

j'aimerais savoir s'il est possible de faire en langage C ceci:

j'ai par exemple un fichier test.txt

dans lequel il se trouve la chaine de caractere suivante: toto

est il possible de remplacer cette chaine de caractere par une autre préalablement demander à l'utilisateur.

exemple:

l'utilisateur saisit comme chaine de remplacement tom

Puis le programme ouvre le fichier test, et compare chaque chaine de caractere , et quand il trouve la chaine toto, il la remplace par tom .

c'est possible ou pas ?? (je suis pas sure d'être bien clair lol)

Merci pour votre aide éventuelle.

10 réponses

Messages postés
1
Date d'inscription
samedi 23 octobre 2004
Statut
Membre
Dernière intervention
25 septembre 2010
3
Si le fichier est pas trop gros, tu peux le lire en mémoire, faire les remplacements et réécrire le fichier. Voilà une fonction pour remplacer.
Exemple d'utilisation:

   rpl = 2; /* Remplacements limités */ 
   chaine = remplacer("AAAAAAA", "AA", "BIP", &rpl); 
   printf("Remplacements: %d\tResultat: [%s]\n\n", rpl, chaine); 
   /* Remplacements: 2        Resultat: [BIPBIPAAA] */ 
   free(chaine); 


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

/* ------------------------------------------------------------------------ 
  Nom        : <remplacer>  
  Creation   : Thierry Husson, Sept 2010 
  But        : Cherche et remplace une sous-chaine par une autre 
  Parametres : 
        str     : Chaine de caractères dans laquelle on fouille 
        oldstr  : Sous-chaine recherchée 
        newstr  : Sous-chaine de remplacement 
        count   : Pointeur vers un entier ou NULL si optionnel 
          Entrée: Nombre de remplacements maximum à faire. 
                  Si < 1 ou NULL, fait des remplacements illimités 
          Sortie: Nombre de remplacements faits ou -1 si erreur 
  Retour     : Pointeur vers une nouvelle chaine de caractères 
               avec les remplacements faits ou NULL si erreur 
  Remarques  :  
     - Tient compte des majuscules/minuscules (case sensitive) 
       Autrement, remplacez les fonctions "strstr" par "strcasestr" 
     - Fait systématiquement une copie de la chaine en entrée 
       comme résultat de la fonction (pointeur sur nouvelle chaine) 
------------------------------------------------------------------------ */ 
char* remplacer(const char *str, const char *oldstr, 
                const char *newstr, int *count) 
{ 
   const char *tmp = str; 
   char *result; 
   int   found = 0; 
   int   length, reslen; 
   int   oldlen = strlen(oldstr); 
   int   newlen = strlen(newstr); 
   int   limit = (count != NULL && *count > 0) ? *count : -1;  

   /* Compte le nombre de fois que la chaine originale est trouvée */ 
   while ((tmp = strstr(tmp, oldstr)) != NULL && found != limit) 
      found++, tmp += oldlen; /* Reprend après la chaine trouvée */ 
    
   /* Calcule l'espace mémoire nécessaire pour la nouvelle chaine */ 
   length = strlen(str) + found * (newlen - oldlen); 
   if ( (result = (char *)malloc(length+1)) == NULL) { 
      fprintf(stderr, "Not enough memory\n"); 
      found = -1; 
   } else { 
      tmp = str; 
      limit = found; /* Compteur à rebours */ 
      reslen = 0;  /* longueur en cours du résultat */ 
      /* Pour chaque sous-chaine trouvée, on met celle de remplacement */ 
      while ((limit-- > 0) && (tmp = strstr(tmp, oldstr)) != NULL) { 
         length = (tmp - str); /* Nombre de caractères inchangés */ 
         strncpy(result + reslen, str, length); /* Copie partie inchangée */  
         strcpy(result + (reslen += length), newstr); /* Ajoute newstr */ 
         reslen += newlen; 
         tmp += oldlen; 
         str = tmp; 
      } 
      strcpy(result + reslen, str); /* Ajoute fin de la chaine inchangée */ 
   } 
   if (count != NULL) *count = found; 
   return result; 
} 
4
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci

Messages postés
627
Date d'inscription
mardi 12 juin 2007
Statut
Membre
Dernière intervention
19 février 2016
390
C'est bien sur possible...

Ça fait un moment que j'ai fait du C et je connais pas toutes les fonctions par coeur.
Je sais pas si tu es un débutant ou non alors, je vais te donner les fonctions clés à utiliser :

fopen : permet d'ouvrir un fichier en lecture/écriture/les deux ([ http://gilles.chagnon.free.fr/cours/cgi/cours5.html )]
strcmp : permet de comparer deux chaines de charactère ([ https://www.ltam.lu/tutoriel_ansi_c/prg-c81.htm )]

je t'avoue que je ne me souvient plus comment remplacer une chaine de charactère par une autre en C (il existe des fonctions replace en C++ et C#, mais en C, j'oublie)

Si tu as besoin de plus de précisions, dis le!
Merci pour ta réponse !!

j'ai quelques petites notions en C.

ouvrir un fichier je connaissais

la comparaison de chaque chaine de caractere avec celle que je saissit au début se fait avec strcmp mais pour qu'il ne le fasse pas qu'avec la premiere chaine de caractere du fichier, il faut que je place le strcmp dans une boucle, et que je l'incremente à a chaque fois, ou il y a plus simple ??
J'ai un fichier test.txt qui contient une chaine de caractère toto, je souhaite remplacer cette chaine par une autre préalablement saisie par l'utilisateur.

Est ce possible en C d'ouvrir mon fichier test.txt afin de chercher la chaine toto et de la remplacer par celle saisie par l'utilisateur ??
Messages postés
1867
Date d'inscription
vendredi 15 avril 2005
Statut
Membre
Dernière intervention
24 juillet 2014
337
Bonjour,

Je pense que tout d'abord, dans ton fichier il faut que toutes les chaines aient la même longueur allouée. On supposera que c'est MAX_CHAINE. Sinon il faut déplacer toute la suite des nom, c'est plutôt ingérable...
char chaine[MAX_CHAINE];
FILE* fp=fopen("test.txt" , "rt");
void *ret;

while ((ret = fgets(chaine , MAX_CHAINE , fp)) != NULL && strcmp(chaine , "toto") ) ;
 
if (ret == NULL) {
  /* Nom non trouvé */
 }
else {
  /* Nom trouvé */
  fseek(fp, - sizeof(char)*MAX_CHAINE , SEEK_CUR); /* On se replace au debut de la chaine trouvée */
  fprintf(fp , "nouveau_nom");
}  

Je n'ai pas testé, mais ça peut peut-être t'aider.
je n'ai pas précisé mais la chaine initiale et celle qui la remplace ne sont pas de la même longueur
je viens d'essayer d'adapter ta solution à mon programme mais cela ne modifie pas mon fichier texte.

chaine et toto seront de longueurs différentes en faite.

j'ai rajouté des printf dans le IF et le ELSE et a chaque fois ,que les chaines soient identiques ou différentes j'arrive au printf du else.
Messages postés
1867
Date d'inscription
vendredi 15 avril 2005
Statut
Membre
Dernière intervention
24 juillet 2014
337
Ce n'est pas les longueur de chaines qui doivent être constantes mais l'espace consacré à la chaine dans le fichier.
Ton fichier doit être structuré comme un tableau, avec pour chaque case un espace reservé de longueur MAX_CHAINE.
Supposons que MAX_CHAINE est 5.
On entre les chaines :
a
ba
et
blob
j

Il faut que tu te débrouilles pour que ton fichier ressemble à :
a \n 0 0 0 b a \n 0 0 e t \n 0 0 b l o b \n j \n 0 0 0 0


Si tu ne fais pas cela, comprends bien que tu devrais déplacer tout ce qui suit dans le fichier en cas de changement de taille de la chaine (fort probable !)
je n'ai qu'une chaine à remplacer dans mon fichier:

toto -> nouveau_mot
Messages postés
1867
Date d'inscription
vendredi 15 avril 2005
Statut
Membre
Dernière intervention
24 juillet 2014
337
Et bien dans ce cas tu n'a qu'a réserver l'espace MAX_CHAINE juste pour les champs susceptibles d'êtres changés.
extrait de mon fichier:

fdsfsddsfsd fsfdsfsd

zze dsf effef

f dfsdf toto
fsdfsd

fdsfsfsdffer
Messages postés
1867
Date d'inscription
vendredi 15 avril 2005
Statut
Membre
Dernière intervention
24 juillet 2014
337
Oui mais on ne sait pas à quoi ça correspond... Qu'as-tu entré ?

Fait plutôt un "od -c | less" on y verra plus clair :)
c'est un extrait de mon fichier de base par exemple. je souhaite remplacer toto par nouveau.

Je ne parviens pas à modifier mon fichier pour le moment

voici ton code avec mes variables:

toto = chaine à remplacer
les chaines nes ont pas de la même longueur.


while (((ret = fgets(chaine_saisie_par_user,11,fp))!= NULL) && strcmp(chaine_saisie_par_user,"toto"))
{
if (ret == NULL)
{
printf("mot nom trouvé");
}
else
{

fseek(fp, - sizeof(char)*11,SEEK_CUR);
fprintf(fp,"%s",chaine_saisie_par_user);
printf("remplacement effectué\n");
fclose(fp);
}
}
Messages postés
1867
Date d'inscription
vendredi 15 avril 2005
Statut
Membre
Dernière intervention
24 juillet 2014
337
attend, mon code c'est pas ça...
Déjà le if n'est pas dans le while...

Regarde bien :)
a oui effectivement.

j'ai corrigé cette erreur mais maintenant il ne trouve jamais le mot

mot non trouvé
Messages postés
1867
Date d'inscription
vendredi 15 avril 2005
Statut
Membre
Dernière intervention
24 juillet 2014
337
euh oui effectivement.
Je pense qu'il faut utiliser fread() et non fgets. Comme ça il lira la chaine jusqu'au caractère d'indice MAX_CHAINE même si la chaine est plus petite. Mais ca c'est dans le cas ou tous les champs du fichiers ont la longueur MAX_CHAINE (reservée).
Sinon il faut que tu te débrouilles pour arriver à l'endroit ou il y a la chaine recherchée.