Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Copie de chaine de caracteres sans succes

33 réponses
Avatar
bpascal123
Bonjour,
Ce code ne fonctionne pas et il me semble pas il y a avoir de
difficult=E9s. Je pense avoir fait une erreur quelque part.
Voici:

#include <stdio.h>

int main(void)
{
char Ch1[40] ;
char Suj[80] ;
char FinSuj[60] ;

int i, j, k ;
int OK ;

printf("\n\nEntrez la chaine Ch1 : ") ;
fgets(Ch1, 40, stdin) ;
printf("\nEntrez la chaine Suj. : ") ;
fgets(Suj, 80, stdin) ;

OK =3D 1 ;

for ( i =3D 0 ; OK && Suj[i] ; i++ )
if ( Suj[i] =3D=3D Ch1[0] )
{
for ( j =3D 1 ; Ch1[j] && (Ch1[j] =3D=3D Suj[i+j] ) ; j++ )
;
if ( Ch1[j] =3D=3D '\0' )
OK =3D 0 ;
}

if (!OK)
{
/* copie de la fin de Suj dans FinSuj */
i-- ;
for ( k =3D 0 ; Suj[i+j+k] ; k++ )
FinSuj[k] =3D Suj[i+j+k] ;
FinSuj[k] =3D '\0' ;
}

printf("\n%s", FinSuj) ;

printf("\n\n");

return 0 ;
}

10 réponses

1 2 3 4
Avatar
espie
In article ,
wrote:
Bonjour,
Ce code ne fonctionne pas et il me semble pas il y a avoir de
difficultés. Je pense avoir fait une erreur quelque part.
Voici:

#include <stdio.h>

int main(void)
{
char Ch1[40] ;
char Suj[80] ;
char FinSuj[60] ;

int i, j, k ;
int OK ;

printf("nnEntrez la chaine Ch1 : ") ;
fgets(Ch1, 40, stdin) ;



fgets a une valeur de retour, c'est une fonction d'entree -> commence
par verifier que tout s'est bien passe, ensuite on en reparle.

(et accessoirement, un printf("Chaine: "); peut ne rien afficher.
Il FAUT le fflush(stdout); derriere si tu veux etre sur d'avoir quelque
chose...)
Avatar
Benoit Izac
Bonjour,

le 29/11/2009 à 16:13, bpascal a écrit dans le message
:

Ce code ne fonctionne pas



Pour en être sûr, il faudrait savoir ce qu'il est censé faire.

et il me semble pas il y a avoir de difficultés. Je pense avoir fait
une erreur quelque part. Voici:

#include <stdio.h>

int main(void)
{
char Ch1[40] ;
char Suj[80] ;
char FinSuj[60] ;

int i, j, k ;
int OK ;

printf("nnEntrez la chaine Ch1 : ") ;



fflush(stdout);

fgets(Ch1, 40, stdin) ;



Il faut toujours tester le retour de fgets (et même faire un peu plus
pour être sûr de Ch1[]). Par exemple si je rentre 50 caractères et que
j'appuie sur ENTER (ça fait donc 51 comme le Pastis), tu auras 39
caractères dans Ch1 et les autres dans Suj[] (12 caractères). Je ne
pense pas que ce soit ce que tu attends.

printf("nEntrez la chaine Suj. : ") ;
fgets(Suj, 80, stdin) ;

OK = 1 ;

for ( i = 0 ; OK && Suj[i] ; i++ )
if ( Suj[i] == Ch1[0] )
{
for ( j = 1 ; Ch1[j] && (Ch1[j] == Suj[i+j] ) ; j++ )



Ici de devrait vérifier que tu n'es pas non plus en dehors de Suj[] car
il peut y avoir n'importe quoi derrière.

for (j = 1; Suj[i+j] && Ch1[j] && Ch1[j] == Suj[i+j]; j++)

;
if ( Ch1[j] == '' )
OK = 0 ;
}

if (!OK)
{
/* copie de la fin de Suj dans FinSuj */
i-- ;



Même chose que précédemment, il faut t'assurer que Suj[i+j+k] soit
toujours dans Suj[] (dans ce qui a été entrée via stdin).

for ( k = 0 ; Suj[i+j+k] ; k++ )
FinSuj[k] = Suj[i+j+k] ;
FinSuj[k] = '' ;
}

printf("n%s", FinSuj) ;

printf("nn");

return 0 ;
}



--
Benoit Izac
Avatar
Benoit Izac
Bonjour,

le 29/11/2009 à 16:13, bpascal a écrit dans le message
:

Je suis pas sûr de ce que tu as voulu faire, j'ai légèrement modifié ton
code et rajouté pas mal de commentaires.


#include <stdio.h>
#include <stdlib.h> /* pour exit(3) */

/* c'est plus pratique ; quand on veut modifier une taille, on a pas
* besoin de parcourir tout le programme */
#define STR_S 80
#define SUB_S 40
#define END_S 60


/* Demande une chaine et un sous-chaine. Si la sous-chaine apparaît
* dans la chaine principale le programme affiche ce qui reste dans la
* chaine principale après la première occurrence de la sous-chaine. */
int
main(void)
{

char str[STR_S]; /* la chaine principale */
char sub[SUB_S]; /* la sous-chaine */
char end[END_S]; /* la fin de la chaine */

int i, j, k;
int found;

/* ici il faut bien voir qu'aucune des variables ci-dessus n'a été
* initialisées. Il ne faut surtout pas les utiliser car elles
* peuvent contenir n'importe quoi, surtout pas de
* printf("%s", end) */

printf("Entrez la chaine principale : ");
/* comme il n'y a pas de 'n' à la fin du printf, pour être sûr de
* l'affichage il faut forcer le vidage du buffer de sortie */
fflush(stdout);

if (fgets(str, STR_S, stdin) == NULL) {
/* il y a eu une erreur, normalement, il faudrait chercher
* à savoir d'où elle vient ; on va faire simple, on se
* contente de quitter le programme */
exit(EXIT_FAILURE);
}

/* on va vérifier qu'il n'y a pas eu trop de caractères : on
* cherche la fin de la chaine puis on vérifie que le caractère
* précédent est bien un retour à la ligne */
for (i = 0; str[i]; i++)
;
/* i est au '' qui marque la fin de la chaine, on recule */
i--;
if (str[i] != 'n')
/* il n'y a pas de retour à la ligne donc il y a trop de
* caractères dans stdin : on quitte le programme */
exit(EXIT_FAILURE);
/* pendant qu'on est sur le 'n', on va le supprimer */
str[i] = '';


/* la même chose pour sub, une fonction serait pratique ici plutôt
* que de recopier le code */
printf("Entrez la sous chaine : ");
fflush(stdout);
if (fgets(sub, SUB_S, stdin) == NULL)
exit(EXIT_FAILURE);
for (i = 0; sub[i]; i++)
;
i--;
if (sub[i] != 'n')
exit(EXIT_FAILURE);
sub[i] = '';

/* pour le moment on à rien trouvé */
found = 0;

/* on parcourt str[] jusqu'à ce qu'on trouve */
for (i = 0; str[i]; i++) {
if (str[i] == sub[0]) {
/* on a trouvé */
found = 1;
/* on parcourt sub[] */
for (j = 1; sub[j]; j++) {
if (str[i+j] != sub[j]) {
/* c'est différent, on arrête de parcourir sub[] */
found = 0;
break;
}
if (str[i+j] == '') {
/* on est à la fin de str[], on sort */
found = 0;
break;
}
}
if (found)
/* on a trouvé on arrête de parcourir str[] */
break;
}
}

if (found) {
/* i était là où on avait trouvé (str[i] == sub[0])
* j était au '' de sub[]
* i + j sera donc au bon endroit
* attention à ne pas écrire plus loin que la taille de k[]
* on garde une place pour le zéro final */
for (k = 0; str[i + j + k] && k < (END_S - 1); k++)
end[k] = str[i + j + k];

end[k] = '';
printf("%sn", end);
}

return 0;
}

--
Benoit Izac
Avatar
bpascal123
J'avoue passer beaucoup de temps sur ce code mais d'un point de vu
implémentation d'un algorithme basique je le trouve intéressant pour
me pencher dessus.

Donc quand j'exécute le code avec par exemple : Ch1 = jour ... Ch2 =
bonjour ... ça fonctionne, le "trouve!" de la condition if s'affiche.
Cependant quand j'exécute avec Ch1 = bon ... Ch2 = bonjour ... rien
ne s'affiche

Voici:

#include <stdio.h>

int main(void)
{
char Suj[100] ;
char Ch1[40] ;
char Ch2[40] ;
char FinSuj[80] ;

int i, j, k ;
int ok = 1 ;

printf("nnEntrez la chaine a rech. Ch1 : ") ;
fgets(Ch1, 40, stdin) ;
printf("nEntrez la chaine Sujet. : ") ;
fgets(Suj, 80, stdin) ;


for ( i = 0 ; ok && Suj[i] ; i++ )
{
if ( Suj[i] == Ch1[0] )
{
for ( j = 1 ; Ch1[j] && (Ch1[j] == Suj[i+j]) ; j++ )
;
if ( Ch1[j] == '' )
{
ok = 0 ;
printf("ntrouve!") ;

}

}
}

printf("nn") ;

return 0 ;
}


Je ne souhaite pas faire appel aux pointeurs et aux fonctions autres
comme fflush car d'après le tutorial, ça n'est pas nécessaire. Je
connais un peu le mécanisme des pointeurs mais ne sachant pas si C
sera un langage sur lequel je vais concentrer mes efforts sur le long
terme, je porte mes efforts sur les algos. Je sais vous allez me dire
que C n'est pas bon pour les algos. Ca fait plusieurs que j'apprends
et j'ai pas envie de faire machine arrière.

Merci
Pascal
Avatar
candide
a écrit :

Je ne souhaite pas faire appel aux pointeurs et aux fonctions autres
comme fflush car d'après le tutorial, ça n'est pas nécessaire.




????????


Et quel est ce tutorial qui écrit ça?


terme, je porte mes efforts sur les algos.



Non, là tu portes tes efforts sur les entrées/sorties

Je sais vous allez me dire
que C n'est pas bon pour les algos.




Si mais ça dépend des algos et ça dépend de ce que tu veux faire. Mais
tu peux aller assez loin sans pointeur, juste avec

-- des fonctions (que tu écris toi-même bien sûr)
-- des instructions for, while, if/else
-- des tableaux
-- printf
-- éventuellement des structures
-- quelques opérateurs bien sûr
Avatar
espie
In article ,
wrote:
Je ne souhaite pas faire appel aux pointeurs et aux fonctions autres
comme fflush car d'après le tutorial, ça n'est pas nécessaire.



Mauvais tutoriel, changer de tutoriel.

Il est *necessaire* d'appeler fflush apres un printf sans "n" au bout
si tu veux etre sur que les choses s'affichent avant le prochain fgets/scanf.

Si le meme tutoriel t'encourage aussi a ne pas verifier le code de retour
de fgets, c'est definitivement un tutoriel a eviter !

Comme repete 25 fois ici et ailleurs, le C est un langage carrement *hostile*
aux debutants. Toutes les mauvaises habitudes que tu prends maintenant vont
te faire gagner 30 secondes sur le coup, et te faire perdre des heures plus
tard. A toi de voir...
Avatar
bpascal123
On Dec 1, 7:26 pm, (Marc Espie) wrote:
In article .com>,

wrote:
>Je ne souhaite pas faire appel aux pointeurs et aux fonctions autres
>comme fflush car d'après le tutorial, ça n'est pas nécessaire.

Mauvais tutoriel, changer de tutoriel.



C'est un conseil ou un ordre?
Tu es le président de la république :)

Réponse : voici l'adresse du tuto :

http://www.ltam.lu/Tutoriel_Ansi_C/
Exercice 8.23

La solution ne montre que l'usage de stdio.h ... car les exercices
appartiennent à chaque chapitre. Même si le code n'est pas actualisé,
je trouve l'ouvrage de cet auteur pédagogique. Pouvez-vous me montrer
quelque chose de mieux (tuto avec cours et exercices?). Alors est-ce
que je gagnerais à changer de tuto? Je vous renvoie la balle vous qui
critiquez à chacun de mes posts. Est-ce que je dois changer de groupe?

Il est *necessaire* d'appeler fflush apres un printf sans "n" au bout
si tu veux etre sur que les choses s'affichent avant le prochain fgets/sc anf.



Si le meme tutoriel t'encourage aussi a ne pas verifier le code de retour
de fgets, c'est definitivement un tutoriel a eviter !



J'ai volontairement remplacé le gets du code initiale par fgets (code
propre sans warning).

Comme repete 25 fois ici et ailleurs, le C est un langage carrement *host ile*
aux debutants. Toutes les mauvaises habitudes que tu prends maintenant vo nt
te faire gagner 30 secondes sur le coup, et te faire perdre des heures pl us
tard. A toi de voir...



C'est tout vu, merci
Avatar
bpascal123
Je trouve le code très simple. J'ai déjà fait cet exercice il y a 2 o u
3 mois. Dans ma démarche d'autodidacte, j'étais arrivé au chapitre de s
pointeurs, dans ce groupe fr.comp.lang.c ou comp.lang.c on m'a
fortement conseillé de coder avec des fonctions que je déclare et
appellent et j'ai décidé de faire une révision pour mieux approcher
les algorithmes avec les pointeurs même si j'avais déjà commencé. J e
pense que les fonctions des bibliothèques pourraient dépanner mais
pour apprendre je ne pense pas qu'aller trop vite est intéressant pour
la suite. C'est vrai qu'il y a des périodes ou je vais lentement.
C'est comme ça, c'est peut-être le changement de temps. C'est un autre
sujet, un autre groupe svp.

Pour reprendre le fil, ce code me paraît très carré càd plus que
cohérent et quand j'écris pour Ch1 : bon Ch2 jour, il ne se passe rien
alors que quand j'écris pour Ch1: jour et Ch2 : bonjour

???
Avatar
Lucas Levrel
Le 1 décembre 2009, a écrit :

Donc quand j'exécute le code avec par exemple : Ch1 = jour ... Ch2 > bonjour ... ça fonctionne, le "trouve!" de la condition if s'affiche.
Cependant quand j'exécute avec Ch1 = bon ... Ch2 = bonjour ... rien
ne s'affiche



Tu n'exécutes pas avec Ch1 = bon et Suj = bonjour, parce que ces chaînes
ne sont pas définies dans le source. Tu les entres au clavier. Donc tu
exécutes ce code, puis tu entres... quoi ? Pose-toi la question
précisément : que tapes-tu exactement sur le clavier ?

Essaye ça pour comparer :

#include <stdio.h>

int main(void)
{
char Suj[100]="bonjour" ;
char Ch1[40]="bon" ;

int i, j ;
int ok = 1 ;

for ( i = 0 ; ok && Suj[i] ; i++ )
{
if ( Suj[i] == Ch1[0] )
{
for ( j = 1 ; Ch1[j] && (Ch1[j] == Suj[i+j]) ; j++ )
;
if ( Ch1[j] == '' )
{
ok = 0 ;
printf("ntrouve!") ;

}

}
}

printf("nn") ;

return 0 ;
}

--
LL
Avatar
Marc Boyer
Le 02-12-2009, a écrit :
On Dec 1, 7:26 pm, (Marc Espie) wrote:
In article ,
wrote:
>Je ne souhaite pas faire appel aux pointeurs et aux fonctions autres
>comme fflush car d'après le tutorial, ça n'est pas nécessaire.

Mauvais tutoriel, changer de tutoriel.



C'est un conseil ou un ordre?



On peut aller regarder le dit tutoriel, et après
10mn, le classer dans la longue liste des choses
trop approximatives pour être utilisable.

http://www.ltam.lu/Tutoriel_Ansi_C/



Fabuleux.
Premier exemple: hello word:

#include <stdio.h>
main()
/* Notre premier programme en C */
{
printf("hello, worldn");
return 0;
}

Au paragraphe "3.1.1. Les types entiers", nous apprenons que les
int sont codés sur deux octets.

Le paragraphe "3.7.1. Les conversions de type automatiques" est un
régal en ce qui concerne les types non signés.

Mais bon...

Marc Boyer
--
En prenant aux 10% des francais les plus riches 12% de leurs revenus,
on pourrait doubler les revenus des 10% les plus pauvres.
http://www.inegalites.fr/spip.php?article1&id_mot0

--
En prenant aux 10% des francais les plus riches 12% de leurs revenus,
on pourrait doubler les revenus des 10% les plus pauvres.
http://www.inegalites.fr/spip.php?article1&id_mot0
1 2 3 4