Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 04/11/2007, à 10:49

--jb63--

Problème de compilation ... de segmentation

Bonjour à tous !
Voila, j'ai un p'tit soucis : étant en iut informatique, j'ai des partiels cette semaine ... notamment en algo big_smile sad: mad:
Donc comme je suis un élève très studieux (:rolleyes::D) j'me suis entrainé a reproduire "le jeu du pendu" en C ... Mais j'ai un problème lorsque je compile : j'ai un warning.
Jusque là pas de soucis en principe, on peut continuer, mais alors j'ai ensuite une erreur de segmentation lorsque je lance le jeu (au niveau du "Avez vous une proposition (o/n) : ").

Voici mon code :

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


void pendu (void)
{
	char motAdeviner[27], motAdevinerC[27], remplissage[27];
	char c, proposition, rep; 
	int etape, l, i, etapeCourante=1, etapeRestante;	

	printf("Donnez le mot a deviner : ");
	scanf("%s",motAdeviner);
	printf("Donnez le nombre d'etape : ");
	scanf("%d",&etape);

	l=strlen(motAdeviner);

	for (i=0;i<l;i++)
		remplissage[i]='-';
		remplissage[l]='\0';
	printf("%s\n", remplissage);
	printf("Vous avez %d etapes pour trouver ce mot !\n",etape);

	while (etapeCourante <= etape)
	{	printf("\nEtape : %d\n", etapeCourante);
		printf("Proposez une lettre : ");
		scanf("%*c%c",&c);
		for (i=0;i<l;i++)
		if (motAdeviner[i]==c)
			remplissage[i]=c;
			printf("%s\n",remplissage);
			printf("Avez-vous une proposition (o/n) : ");
			scanf("%*c%c",&rep);
			if (rep=='o')
			{	printf("Mot : ");
				scanf("%*c%s",&proposition);
			}
			if (strcmp(proposition,motAdeviner)==0)
			{	printf("Bravo !");
				printf("Vous avez trouve le mot %s en %d etape(s)", motAdeviner, etapeCourante);
			}
		etapeCourante++;
	}	
	

	if (etapeCourante>etape)
		printf("PENDU !\n");

}

int main (void)
{
	pendu();
	return 0 ;
}

Si quelqu'un pouvait m'aider ...

En vous remerciant ! wink

#2 Le 04/11/2007, à 11:18

robrob

Re : Problème de compilation ... de segmentation

le scanf("%*c%s",&proposition); devrait plutôt être un scanf("%s",proposition);
Proposition devant être déclarée de même manière que motAdeviner.

Sinon quand je compile j'ai:
pendu.c:10: warning: unused variable ‘etapeRestante’
pendu.c:8: warning: unused variable ‘motAdevinerC’

C'est pas très élégant wink

Dernière modification par robrob (Le 04/11/2007, à 11:20)

Hors ligne

#3 Le 04/11/2007, à 11:48

--jb63--

Re : Problème de compilation ... de segmentation

Tout d'abord, merci de ta réponse wink
alors ...
...pour ce qui est des deux variables non-utilisées, c'est juste que j'avais prévu de les utiliser plus tard pour la confirmation du mot a deviner et le calcul d'étapes restantes... big_smile
... en revanche, j'ai bien fais la modif' pour le "%*c" mais ça ne change rien, mon erreur est toujours la sad.

#4 Le 04/11/2007, à 11:57

Watchwolf

Re : Problème de compilation ... de segmentation

Utilise fgets a la palce de scanf. Ensuite tu peut faire tte les conversions que tu veut avec sscanf

Hors ligne

#5 Le 04/11/2007, à 12:18

--jb63--

Re : Problème de compilation ... de segmentation

Ah oui ! j'l'avais oublier ce fameux "fgets" .
Mais donc par exemple, il faut que je remplace :

    printf("Donnez le mot a deviner : ");
    scanf("%s",motAdeviner);

par

    printf("Donnez le mot a deviner : ");
    fgets(motAdeviner,27,stdin);
    motAdeviner[strlen(proposition)-1]='\0'

C'est bien ça ? :/ (si j'me réfère à mon cours ...)

Mais c'est pas tous les scanf que j'dois remplacer par fgets...
j'vois pas trop comment m'y prendre en fait, on a travailler avec les fgets seulement à la dernière séance, donc j'ai pas tout bien assimiler ...:(

merci en tout cas ;)

#6 Le 04/11/2007, à 14:00

Watchwolf

Re : Problème de compilation ... de segmentation

fgets te renvoie la chaine de caractère saisie par l'utilisateur? le '\n' compris. Ta dernière ligne sert a supprimer le \n.

voila. scanf c'est uine méthode à ne pas utiliser car le buffer n'en sort pas propre.

Hors ligne

#7 Le 04/11/2007, à 14:19

--jb63--

Re : Problème de compilation ... de segmentation

Ah ok ! wink
Mais alors quels sont les scanf que j'dois remplacer par des fgets dans mon script ? hmm
Et ça devrais fonctionner au fait quand j'aurais fais ça ?

#8 Le 04/11/2007, à 14:23

AuraHxC

Re : Problème de compilation ... de segmentation

En general tu dois remplacer tout tes scanf par fgets.
Il faut éviter au maximum de l'utiliser big_smile

Hors ligne

#9 Le 04/11/2007, à 14:28

--jb63--

Re : Problème de compilation ... de segmentation

D'accord ! ... j'étais pas au courant ! big_smile
Mais alors, c'est donc de là qu'elle vient mon erreur de segmentation ...:o

#10 Le 04/11/2007, à 14:55

AuraHxC

Re : Problème de compilation ... de segmentation

Pas forcement ! j'ai pas regardé ton code... Quand j'ai commencé la prog, j'utilisais aussi des scanf et sans spécialement des erreurs de segmentation. Peut être un problème d'algo, enfin en général c'est quand tu tente d'accéder a une zone mémoire où tu n'as pas le droit.

Hors ligne

#11 Le 04/11/2007, à 15:01

AuraHxC

Re : Problème de compilation ... de segmentation

Apparement ton warning vient de ton strcmp :
pendu.c:38: warning: passing argument 1 of ‘strcmp’ makes pointer from integer without a cast

Le prototype de strcmp c'est : int strcmp (const char *s1, const char *s2);

Il me semble que tu lui passe un char en paramètre a un moment, j'ai pas trop regardé, vérifie et tu redis wink

Hors ligne

#12 Le 04/11/2007, à 15:14

--jb63--

Re : Problème de compilation ... de segmentation

euh ... j'comprend pas bien c'que tu veux dire en fait ! big_smile (désolé j'débute sad) ...
Alors en fait, la seule chose que je fais en utilisant strcmp c'est :

 if (strcmp(proposition,motAdeviner)==0)

#13 Le 04/11/2007, à 15:30

$Gaël$

Re : Problème de compilation ... de segmentation

AuraHxC a écrit :

En general tu dois remplacer tout tes scanf par fgets.
Il faut éviter au maximum de l'utiliser big_smile

Ah?? Serait-il possible d'avoir plus de détails ?


Ubuntu is an ancient african word meaning : "I can't configure Debian".

Hors ligne

#14 Le 04/11/2007, à 15:59

--jb63--

Re : Problème de compilation ... de segmentation

aaaaaaaaahhhhhh ! ça y'est !
j'ai compris, quelqu'un m'a expliqué : il faut en fait rajouter un exit(1) dans ma condition "if (strcmp....)" comme ceci :

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


void pendu (void)
{
    char motAdeviner[27], motAdevinerC[27], remplissage[27], proposition[27];
    char c, rep; 
    int etape, l, i, etapeCourante=1, etapeRestante;    

    printf("Donnez le mot a deviner : ");
    scanf("%s",motAdeviner);
    printf("Donnez le nombre d'etape : ");
    scanf("%d",&etape);

    l=strlen(motAdeviner);

    for (i=0;i<l;i++)
        remplissage[i]='-';
        remplissage[l]='\0';
    printf("%s\n", remplissage);
    printf("Vous avez %d etapes pour trouver ce mot !\n",etape);

    while (etapeCourante <= etape)
    {    printf("\nEtape : %d\n", etapeCourante);
        printf("Proposez une lettre : ");
        scanf("%*c%c",&c);
        for (i=0;i<l;i++)
        if (motAdeviner[i]==c)
            remplissage[i]=c;
            printf("%s\n",remplissage);
            printf("Avez-vous une proposition (o/n) : ");
            scanf("%*c%c",&rep);
            if (rep=='o')
            {    printf("Mot : ");
                scanf("%*c%s",&proposition);
            }
            if (strcmp(proposition,motAdeviner)==0)
            {    printf("Bravo !");
                printf("Vous avez trouve le mot %s en %d etape(s)", motAdeviner, etapeCourante);
                exit(1);
            }
        etapeCourante++;
    }    
    

    if (etapeCourante>etape)
        printf("PENDU !\n");

}

int main (void)
{
    pendu();
    return 0 ;
}

#15 Le 04/11/2007, à 16:20

robrob

Re : Problème de compilation ... de segmentation

Pourquoi dans 1 cas tu mets:
scanf("%s",motAdeviner);
et dans l'autre:
scanf("%*c%s",&proposition);
(c'est surtout le "&proposition" qui me gène)

Sinon le exit(1) ça fait sortir "brutalement" du programme, ce n'est pas la cause du ton problème (si problème il y a).
Tu peux sortir d'une boucle (while, for, etc...) à l'aide d'un break.

Dernière modification par robrob (Le 04/11/2007, à 16:20)

Hors ligne

#16 Le 04/11/2007, à 16:54

AuraHxC

Re : Problème de compilation ... de segmentation

$Gaël$ a écrit :
AuraHxC a écrit :

En general tu dois remplacer tout tes scanf par fgets.
Il faut éviter au maximum de l'utiliser big_smile

Ah?? Serait-il possible d'avoir plus de détails ?

Très souvent, si il est mal utilisé, cela provoque des erreurs comme des buffers overflow. Mais je pense qu'il y a pas mal de chose sur le net qui en parle.
J'ai vu un article sur developpez.com qui parle de démythifiée le scanf : http://xrenault.developpez.com/tutoriels/c/scanf/#L3.1

Je pointe sur les comportements du scanf mais vous pouvez tout lire wink

Hors ligne

#17 Le 04/11/2007, à 17:19

--jb63--

Re : Problème de compilation ... de segmentation

robrob a écrit :

Pourquoi dans 1 cas tu mets:
scanf("%s",motAdeviner);
et dans l'autre:
scanf("%*c%s",&proposition);
(c'est surtout le "&proposition" qui me gène)

Sinon le exit(1) ça fait sortir "brutalement" du programme, ce n'est pas la cause du ton problème (si problème il y a).
Tu peux sortir d'une boucle (while, for, etc...) à l'aide d'un break.

Oups : exact ! ... erreur de ma part, c'est tout simplement que je n'avais pas déclaré "porposition" comme pointeur au niveau de mes variables au début ... roll
Quant au "%*c", il peut dégager d'après ce que l'on m'avait di ...

Pour le "break", je ne savais pas qu'on pouvait l'utiliser dans le cas d'un "if" aussi ... 'faudra que j'essaies ! roll;)

Grand merci en tout cas à tous ceux qui ce sont mobilisés pour m'aider ! wink;);)

#18 Le 04/11/2007, à 19:36

telliam

Re : Problème de compilation ... de segmentation

ça serait pas plus simple de le compiler en mode debug et de voir ce qui se passe?:P


"- Un intellectuel assis va moins loin qu'un con qui marche."
Maurice Biraud - Un Taxi pour Tobrouk
Michel Audiard

Hors ligne

#19 Le 04/11/2007, à 19:52

Watchwolf

Re : Problème de compilation ... de segmentation

scanf est une fonction à ne pas utiliser tout simplement. Lorsque le scanf va lire le buffer il va seulement récupérer ce qui l'interesse et non tout le buffer. Le buffer n'est alors pas vide apres. C'est dans ces cas que l'on veut utiliser fflush mais c'est pas fait pour les buffer d'entré.

fgets va toujours tout lire jusqu'au \n (compris), il n'y a pas d'ambiguité.

Hors ligne

#20 Le 04/11/2007, à 23:41

darky0505

Re : Problème de compilation ... de segmentation

ben je viens de compiler ton code ca "marche" chez moi sans seg fault, faut juste virer le & de la ligne 36 :

if (rep=='o'){    
     printf("Mot : ");
     scanf("%s",proposition);
}

Bon après c'est sur qu'il faut faire des controles sur les réponses fournies et virer tes scanf (remplacer par fgets comme précisé dans les posts précédents).
Vu ton code tu dois pas faire de C depuis très longtemps mais ton code fonctionne si on lui fournit des réponses "normales" ;-)


DarkY

Hors ligne

#21 Le 09/11/2007, à 20:04

--jb63--

Re : Problème de compilation ... de segmentation

En effet : je suis débutant ! big_smile ... j'suis en IUT Info' depuis septembre donc j'découvre les plaisirs de l'informatique petit à  petit ...
Euh par contre j'ai préféré ne pas utiliser les fgets, j'sais pas vraiment m'en servir pour l'instant donc bon ...:rolleyes:
Faudra que j'regarde aussi ce qu'est le mode "debug" ... j'connais pas ça encore ! big_smile

Bon, pour ce qui est de ce fameux jeu du pendu ... j'ai essayé de l'améliorer un peu pendant la semaine vit' fait ('fallait pas oublier les partiels non plus hmm smile) ... et donc voila ou j'en suis :

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


void pendu (void)
{
	char motAdeviner[27], motAdevinerC[27], remplissage[27], proposition[27];
	char c, rep; 
	int etape, l, i, etapeCourante=1, etapeRestante;	

	printf("\n---------------------------------------------------------------------------------\n");
	printf("Donnez le mot a deviner : ");
	scanf("%s",motAdeviner);
	printf("Veuillez confirmer le mot a deviner : ");
	scanf("%s",motAdevinerC);
	while (strcmp(motAdeviner,motAdevinerC)<0 || strcmp(motAdeviner,motAdevinerC)>0)
	{	printf("ATTENTION : Erreur dans la saisie du mot a deviner...recommencez !\n\n");
		printf("Donnez le mot a deviner : ");
		scanf("%s",motAdeviner);
		printf("Veuillez confirmer le mot a deviner : ");
		scanf("%s",motAdevinerC);
	}
	printf("Donnez le nombre d'etape : ");
	scanf("%d",&etape);
	printf("---------------------------------------------------------------------------------\n");

	l=strlen(motAdeviner);
	etapeRestante=etape-etapeCourante;

	for (i=0;i<l;i++)
		remplissage[i]='-';
		remplissage[l]='\0';
	printf("\n\n\n%s\n\n", remplissage);
	printf("Vous avez %d etapes pour trouver ce mot !\n",etape);

	while (etapeCourante <= etape)
	{	printf("\nEtape : %d\n", etapeCourante);
		printf("Proposez une lettre : ");
		scanf("%*c%c",&c);
		for (i=0;i<l;i++)
		if (motAdeviner[i]==c)
			remplissage[i]=c;
			printf("%s\n",remplissage);
			if (strcmp(remplissage,motAdeviner)==0)
			{	printf("Bravo !\n");
				printf("Vous avez trouve le mot \"%s\" en %d etape(s)\n", motAdeviner, etapeCourante);
				exit(1);
			}
			printf("Avez-vous une proposition (o/n) : ");
			scanf("%*c%c",&rep);
			if (rep=='o')
			{	printf("Mot : ");
				scanf("%*c%s",proposition);
				if (strcmp(proposition,motAdeviner)==0)
				{	printf("Bravo !\n");
					printf("Vous avez trouve le mot \"%s\" en %d etape(s) !\n", motAdeviner, etapeCourante);
					break;
				}
				else printf("Mot FAUX ! Il vous reste %d etapes pour trouver le mot...\n",etapeRestante);
			}
			else 
			{	if (etapeCourante==etape)
					printf("\nIl ne vous reste plus d'etapes pour trouver le mot...\n");
				else printf("\nIl vous reste %d etapes pour trouver le mot...\n",etapeRestante);
			}
		etapeCourante++;
	}	
	if (etapeCourante>etape)
	{	printf("  PENDU !\n");
		printf(" _________\n");
		printf("  |/   |\n");
		printf("  |    O\n");
		printf("  |   /|\\\n");
		printf("  |   / \\\n");
		printf("_/_\\_\n");
	}
}

int main (void)
{
	pendu();
	return 0 ;
}

Mais voila ... encore un [dernier] soucis : le nombre "d'étapes restantes" n'est pas modifié au cours des étapes !:mad:
J'ai beau chercher, pas moyen de trouver l'erreur ... sad

#22 Le 09/11/2007, à 20:11

telliam

Re : Problème de compilation ... de segmentation

c'est normal ta ligne

etapeRestante=etape-etapeCourante;

n'est pas à l'interieur du while.
De plus tu n'as pas vraiment besoin de la variable etapeRestante,
il te suffit de mettre etape-etapeCourante


"- Un intellectuel assis va moins loin qu'un con qui marche."
Maurice Biraud - Un Taxi pour Tobrouk
Michel Audiard

Hors ligne

#23 Le 09/11/2007, à 20:35

--jb63--

Re : Problème de compilation ... de segmentation

Ah oui !! en effet ! big_smile
J'te remercie wink ... enfin je VOUS remercie tous !! wink

Bon bah voila, ça fonctionne nikel ... 'reste plus qu'à  faire de trois modif' accessoire pour les erreurs de saisies comme l'un d'entre vous l'avait spécifié tout à  l'heure et ça devrait être bon ! tongue

Faudra juste que j'me renseigne un peu sur l'histoire des "switch ... case..." pour dessiner le "pendu" au fur et à  mesure des mauvaises réponses ... mais y'a le temps pour ça ! big_smile

#24 Le 10/11/2007, à 00:47

darky0505

Re : Problème de compilation ... de segmentation

c'est tres bien pour un 'débutant' smile continue comme ca.


DarkY

Hors ligne

#25 Le 11/11/2007, à 10:15

--jb63--

Re : Problème de compilation ... de segmentation

Merci wink smile

Bon alors ça y'est, j'me suis remis sur le 'tit programme une partie de la journée hier...
J'essaies d'envisager une autre méthode qui autorise un nombre d'erreur autorisées maximum de 10.
Ainsi, j'afficherais l'état du pendu selon le nombre d'erreur avec un "switch...case 1 ..." ...
Mais voila, évidemment : y'a une erreur que j'n'arrive pas à  cerner ! mad

Voici mon code :

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


void pendu (void)
{
	char motAdeviner[27], motAdevinerC[27], remplissage[27], proposition[27];
	char c, rep, modeAffichage; 
	int etape, l, i, etapeCourante=1, etapeRestante, modeJeu, nbErreur=0, nbChance=11;	

	printf("\n---------------------------------------------------------------------------------\n");
	printf("Donnez le mot a deviner : ");
	scanf("%s",motAdeviner);
	printf("\nMode de jeu : \n- [1] par nombre d'erreurs (maximum de 11 erreurs) \n- [2] par nombre d'etapes (fixe par les joueurs) \n\t Choisissez votre mode de jeu : ");
	scanf("%d",&modeJeu);
	
	if (modeJeu==1) 
	{
		printf("--------------------------------------------------------------------------------\n");

		l=strlen(motAdeviner);

		printf("\n\n\nMot recherche : "); 
		for (i=0;i<l;i++)
			remplissage[i]='-';
			remplissage[l]='\0';
		printf("%s\n\n", remplissage);
		printf("Vous disposez d'un maximum de 10 erreurs autorisees avant d'etre pendu pour trouver ce mot compose de %d caracteres !\nLa partie commence ... Bonne chance !\n",i);
		
		while (nbErreur>=0)
		{	printf("\nEtape : %d\n", etapeCourante);
			printf("Proposez une lettre : ");
			scanf("%*c%c",&c);
			for (i=0;i<l;i++)
			if (motAdeviner[i]==c)
			{	remplissage[i]=c;
				printf("%s\n\n",remplissage);
				if (strcmp(remplissage,motAdeviner)==0)
				{	printf("Bravo !\n");
					printf("Vous avez trouve le mot \"%s\" en %d etape(s)\n", motAdeviner, etapeCourante);
					exit(1);
				}
			}
			else
			{	printf("%s\n\n",remplissage);
				nbErreur++;
				printf("Lettre inexistante dans ce mot !\n");
				printf("Nombre d'erreur : %d ", nbErreur);
			}
			etapeCourante++;
		}	
	} 

}

int main (void)
{
	pendu();
	return 0 ;
}

L'erreur se situe au niveau des lignes 45 a 50 manifestement, soit au niveau du "else".
J'n'ai pas de soucis pour compiler, mais c'est lorsque j'utilise le programme que le else s'applique deux fois en fait ... sad

J'réviens donc solliciter votre aide une fois de plus... roll