Probleme avec les pointeurs langage C

Résolu/Fermé
dirkkuyttillidie Messages postés 21 Date d'inscription jeudi 14 août 2008 Statut Membre Dernière intervention 17 décembre 2008 - 14 août 2008 à 23:20
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 15 août 2008 à 23:13
salut tout le monde
voila je travaile sur les pointeurs en C et voila l'énoncé de l'exercice:

Ecrire un programme qui lit deux chaînes de caractères CH1 et CH2 au clavier et élimine toutes les lettres de CH1 qui apparaissent aussi dans CH2. Utiliser deux pointeurs P1 et P2, une variable logique TROUVE et la fonction strcpy.

Exemples:
Bonjour
Bravo
==>
njou

Bonjour
bravo
==>
Bnjou

abacab
aa
==>
bcab

et voila la solution de l'exercice:





#include <stdio.h>
#include <string.h>
main()
{
/* Déclarations */
char CH1[101], CH2[101]; /* chaînes données */
char *P1, *P2; /* pointeurs d'aide dans CH1 et CH2 */
int TROUVE; /* indicateur logique: vrai, si le caractère */
/* actuel dans CH1 a été trouvé dans CH2. */

/* Saisie des données */
printf("Entrez la première chaîne de caractères"
" (max.100 caractères) :\n");
gets(CH1);
printf("Entrez la deuxième chaîne de caractères"
" (max.100 caractères) :\n");
gets(CH2);
/* Eliminer les lettres communes */
/* Idée: Parcourir CH2 de gauche à droite et contrôler */
/* pour chaque caractère s'il se trouve aussi dans CH1. */
/* Si tel est le cas, éliminer le caractère de CH1 à */
/* l'aide de strcpy. */
for (P2=CH2; *P2; P2++)
{
TROUVE = 0;
for (P1=CH1 ; *P1 && !TROUVE ; P1++)
if (*P2==*P1)
{
TROUVE = 1;
strcpy(P1, P1+1);
}
}
/* Affichage du résultat */
printf("Chaîne résultat : \"%s\" \n", CH1);
return 0;
}


et j'arrive pas à comprendre le dernier bloc 'c'est à dire ça:


for (P2=CH2; *P2; P2++)
{
TROUVE = 0;
for (P1=CH1 ; *P1 && !TROUVE ; P1++)
if (*P2==*P1)
{
TROUVE = 1;
strcpy(P1, P1+1);
}
}


je doit savoir la signiffication de chaque ligne s'l vous plait par exemple dans la boucle "for" il ya *P1 && !TROUVE j'ai rien compri
s'il vous plait j'attent votre reponse
pliiiiiiiiiiz
A voir également:

6 réponses

mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
14 août 2008 à 23:56
Le test que tu ne comprends pas consiste à vérifier
- d'une part que P1 n'a pas atteint la fin de la chaîne (sinon *P1 == '\0' rend faux la première opérande du && et le for s'arrête) : c'est une manière abrégée d'écire *P1 != '\0'
- d'autre part que la variable TROUVE ne vaut pas 1 : c'est une manière abrégée d'écrire TROUVE != 0.
... car en C ne l'oublions pas, une variable différente de '\0', NULL, ou 0 vaut la valeur logique "vrai".

Entrons à présent dans le détail du code. On veut écrire ici chaque caractère de CH1 ne figurant pas dans CH2. Pour cela on parcourt un par un les caractères de CH2 (boucle P2), jusqu'à atteindre la fin de la chaîne. On compare ensuite le caractère courant de CH2 (*P2) aux caractères contenus dans CH1. Pour faire ce test on parcourt la chaîne CH1 (boucle P1). On arrête le parcours de CH1 dès que P1 pointe sur un caractère égal à *P2 (TROUVE = 1) ou dès que la chaîne CH1 est entièrement parcouru (TROUVE = 0).

Lorsque *P1 == * P2, cela signifie que le caractère pointé par *P1 doit être supprimé de CH1 (car il figure dans CH2). Pour cela écrase la sous chaîne qui part de P1 par la sous chaîne qui part de P1+1 (strcpy). Ainsi on supprime bien de CH1 le caractère pointé par *P1. C'est un peu tordu comme code mais c'est ce qui est écrit...

Le problème avec cette solution, c'est que vu l'énoncé pour moi avec "Bonjour" et "Bravo" on devrait obtenir "nju". Typiquement les deux "o" de "Bonjour" devraient tout deux être grillés par le "o" de "Bravo". Le code serait plutôt :
#include <string.h>
#include <stdio.h>

int main(){
    const char *str1 = "Bonjour", *str2 = "Bravo";
    int trouve;
    const char *p1,*p2;
    printf("str1 = %s\nstr2 = %s\n",str1,str2);
    for(p1 = str1; *p1 != '\0'; ++p1){
        trouve = 0;
        for(p2 = str2; *p2 != '\0' && !trouve; ++p2){
            if(*p1 == *p2){
                trouve = 1;
                break;
            }
        }
        if(!trouve) printf("%c",*p1);
    }
    printf("\n");
    return 0;
}

En espérant t'avoir éclairé...

Bonne chance
2
dirkkuyttillidie Messages postés 21 Date d'inscription jeudi 14 août 2008 Statut Membre Dernière intervention 17 décembre 2008
15 août 2008 à 01:03
bonsoir,
rien à dire je te le jure meilleure explicaton je te remercie au fond de mon coeur c'est vraiment gentil de m'aider
merci beaucoup mon frère
0
dirkkuyttillidie Messages postés 21 Date d'inscription jeudi 14 août 2008 Statut Membre Dernière intervention 17 décembre 2008
15 août 2008 à 01:28
salut a nouveau,
monsieur lorsqu'on écrit strcpy(p1,P1+1) vous avez dis qu'on écrase la sous chaîne qui part de P1 par la sous chaîne qui part de P1+1 mais on ne peut pas dire (dans cet exemple) que: ona p1 pointe sur ch1 et il a trouvé 'B' qui est exactement le contenu de P2, je vois que lorsqu'on voit P1 ca veut dire l'adresse et on sait que strcpy copie les caracteres et non pas les adresses et alors p1 recoit l'adresse de premier element de ch1 (p1=ch1), donc la notion d'écraser la sous chaîne qui part de P1 par la sous chaîne qui part de P1+1 ne rentre pas dans ma tête
stp aidez moi
0
Salut,

Plusieurs notions se mélangent dans ta tête... c'est compréhensible au départ avec les pointeurs.

1) Intéressons nous au 1er paramètre (et celui là seulement) : la chaine qui va être modifiée
Dans ce cas, il ne faut pas que tu oublies que les paramètres que tu passes au fonction en C se font par "valeur".
C'est à dire que la valeur qui est utilisée à l'intérieur de la fonction est une copie de ton paramètre.
Ainsi les paramètres que tu passes aux fonctions te sont rendues intacts.
Donc, si tu passais le caractère (et non son pointeur), ce caractère te serait rendu avec sa valeur initiale
et non avec sa nouvelle valeur (ta recopie serait donc corrompue, puisque le 1er caractère n'est pas modifié).

2) Intéressons nous au 2eme paramètre (et celui là seulement) : la chaine qui sert de source
Si c'est un pointeur dans ce cas, on va dire qu'il s'agit d'une "convention".
En effet, strcopy pourrait prendre en paramètre un caractère (et non son pointeur) et construire lui même
un pointeur sur ce caractère pour faire le parcours de la chaine (comme dans ta boucle for).
Mais, pour des histoires de lisibilité, il demande un pointeur ce qui signifie que c'est une chaine de caractères
et non un seul caractère que tu lui passes. Et puis, ce serait con que tu lui fasses construire un pointeur
alors que tu en as un sous la main...

Bon courage,
Jérôme.
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
15 août 2008 à 12:48
Je vais tenter une autre explication. Concrètement voilà ce que fait strcpy :
void strcpy(char *dst,const char *src){
  char *pdst;
  const char *psrc;
  for(psrc = src,pdst = dst; *psrc != '\0'; ++psrc,++pdst){
    *pdst = *psrc;
  }
}

Ainsi suppose que l'on considère la chaîne "Bravo" et que l'on fasse le fameux strcpy(p,p+1). En gras je mets le caractère pointé par psrc et en italique le caractère pointé par pdst. Déroulons les itérations de la fonction strcpy (en première ligne, le contenu de la chaîne dst au début de l'itération et en seconde ligne sa valeur à la fin de l'itération) :

Itération 1 :
Bravo\0
rravo\0

Itération 2 :
rravo\0
raavo\0

Itération 3 :
raavo\0
ravvo\0

Itération 3 :
ravvo\0
ravoo\0

Itération 4 :
ravoo\0
ravo\0\0

Itération 5 :
ravo\0\0

psrc == '\0' => fin
A la fin la chaîne dst contient ravo\0\0 ce qui s'écrit "ravo".

C'est plus clair
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
dirkkuyttillidie Messages postés 21 Date d'inscription jeudi 14 août 2008 Statut Membre Dernière intervention 17 décembre 2008
15 août 2008 à 16:02
merci pour votre aide!
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
15 août 2008 à 23:13
De rien bonne continuation ;-)
0