Forum Clubic

[C] [EDIT] Mise a nivo sur les pointeurs - Ca sent l'erreur ne n0oB :)

Salut a tous !

Je veux faire une fonction qui prend en argument une chaine de charactere, qui est ma question, et qui renvoie 1 si l’utilisateur confirme en tapant yes, oui, o, y, majuscule ou minuscule 0 sinon.
Je fais ca, la compile est bonne mais ca renvoie toujours 0
j’ai mis le printf histoire de debugger, mais j’y arrive pas :stuck_out_tongue:
C une histoire de pointeur?

je compile avec gcc
[cpp]
int demanderPredicat(char* question) {

printf("%s (o/n)\n",question);

char *tmp_rep[50];
scanf("%s",&tmp_rep);

if( tmp_rep[1]==“y”
|| tmp_rep[1]==“o” ) {

  return 1;

  } else {

 printf("->%s<-",tmp_rep);
  return 0;

}
}
[/cpp]

Cordialement

essaye gets()

ps : tmp[0] == ‘y’

guillemets simples

pour comparer des chaine strcmp()

juste comme ça, tmp_rep c’est déjà une adresse. Alors évidemment que ça plante !

<= scanf("%s",&tmp_rep);
=> scanf("%s", tmp_rep);

ok les mec je teste tout ca et je vous dit, en C on a vu (a la fac) que les types, les tableaux, les pointeurs et les structs, par contre, pour les E/S ainsi que les lib standards …

Merci tout le monde !

[cpp]
int demanderPredicat(char* question) {

printf("%s (oui/non)\n",question);

char tmp_rep[50];
scanf("%s",tmp_rep);

if( tmp_rep[0]==‘y’
|| tmp_rep[0]==‘o’ ) {

  return 1;

  } else {


  return 0;

}
}
[/cpp]

Affaire classée :jap:

Re !

Je comprend rien du tout au pointeur ou quoi???
jvous explique, je dois programmer un jeu d’allumette (21 allumettes, on en prend 1,2, ou 3 et celui qui tire la derniere a perdu, mais si c’est le jeu de forboyard :ane:)
“intelligent”, c’est a dire avec une IA, pour joueur contre le PayCay !!

C’est un tp de la fac. on a fait un premier programme, et ils donnent des instructions pour creer d autres versions “ameliorées”.

Alors la j’en suis à:

“Créer une structure Joueur contenant comme champs nom et nbPrises et creer 2 variables, une pour le joueur et l autre pour l’ia”
(nbPrises sera affichier a la fin pour l’humain et l’ia)

donc je l’ai fait et ca marche !
Alors pourquoi je poste? et bien dans le code joint ci desous, j’ai creer les variables joueur_humain et joueur_ia de 2 facons differentes, et je les affiches de 2 facons differentes, a savoir un coup je met * devant et d’un autr je le met pas… (et si j’interverti les * entre joueur_humain et joueur_ia ca bug !)

ALors c’est une histoire de pointeur, j’ai quelques lacunes du premier semestre apparament [:matleflou] (j’utilise les pointeurs depuis 2 mois, meaculpa :jap:)

Si quelqu un peut m’expliquer le pourquoi du comment ?
Cordialement

Edit: pour vous y retrouver,

  • ligne 5 je declare la structure,
  • ligne 370 (Dans le main()) je creer les variables + initialise
  • ligne 306 et 314, affichage de 2 manieres différentes !

[cpp]
#include <stdio.h>

struct Joueur {

char *nom[50];
int nbPrises;

};

char *nom1[50];
char *nom2[50];
int firstPlayer;
struct Joueur joueur_humain;
struct Joueur joueur_ia;

/**********************************************************
*

  • retourne le minimum des 2 nombres

**********************************************************/

int min(int a, int b)
{
if(a>b)
{
return b;
} else {
return a;
}
}

/******************************************************
*

  • demanderPredicat(char[] question)

******************************************************/

int demanderPredicat(char* question) {

printf("%s (oui/non)\n",question);

char tmp_rep[50];
scanf("%s",tmp_rep);

if( tmp_rep[0]==‘y’
|| tmp_rep[0]==‘o’ ) {

  return 1;

  } else {


  return 0;

}
}

/**********************************************************
*

  • Affiche la position pos

**********************************************************/

void affichePosition(int Pos)
{

printf("\n");

int i;

for(i=0;i<Pos;i++)
{

printf(" 0 ");

}

printf("\n");

for(i=0;i<Pos;i++)
{

printf(" | ");

}

printf("\n");

for(i=0;i<Pos;i++)
{

printf(" | ");

}

printf("\n\n\n");

}

/*****************************************************
*

  • affiche le coup joué

*****************************************************/
void afficheCoup(int Coup)
{

printf(“Le coup est %i\n”,Coup);

}

/*************************************************************
*

  • Verifie que le coup est jouable dans la position Pos
  • La fonction renverra 1 s’il le coup est jouable, 0 sinon

*************************************************************/

int estCoupValide(int Pos, int Coup)
{
return (Coup>0 && Coup<4 && Pos>Coup);
}

/************************************************************
*

  • joue le coup dans PosDepart et rend la position obtenue

************************************************************/

int joueLeCoup(int PosDepart,int Coup)
{
return (PosDepart-Coup);
}

/************************************************************
*

  • saisi un coup valide et le rend en retour

************************************************************/
int coupSaisi(int Pos)
{

int tmp_coup;
int cpt_tentative=1;

printf(“Entrez un coup entre 1 et %i:\n”,min(Pos-1,3));

while(!estCoupValide(Pos,tmp_coup)) {

  if(cpt_tentative>1)
{

printf("Veuillez entrez un coup entre 1 et %i:\n", min(Pos+1,3));
}


   scanf("%i",&amp;tmp_coup);       
 
   cpt_tentative++;   

} 

  return tmp_coup;   

}

/*********************************************************
*

  • rend 1 si la position Pos est finale, 0 sinon

*********************************************************/
int positionTerminale(int Pos)
{

return (Pos==1);

}

/*********************************************************
*

  • rend 1 si la position Pos est Gagnante, 0 sinon

*********************************************************/

int evalue(int Pos)
{

return (Pos%4!=1);

}

/*********************************************************
*

  • rend 1 si la position Pos est Gagnante, 0 sinon

*********************************************************/

int positionGagnante(int Pos)
{

return evalue(Pos);

}

/**********************************************************
*

  • rend 1 si la postion Pos est Perdante, 0 sinon

**********************************************************/

int positionPerdante(int Pos)
{

return !evalue(Pos);

}

/***********************************************************
*

  • Donne le meilleur coup à jouer dans Pos

***********************************************************/
int trouveCoupIA(int Pos)
{

if(positionGagnante(Pos))
{
int cpt_all=1;
int coup_definitif;

while(cpt_all<4 || estCoupValide(Pos,cpt_all))
{   

  if(positionPerdante(Pos-cpt_all))      
  {
    coup_definitif=cpt_all;
  }

  cpt_all++;

}

return coup_definitif;

} else
{
return 1;
}

}

/***************************************************************
*

  • Moteur du jeu contre l’ IA

***************************************************************/

void moteurIA(int Pos)
{
int tmp_coup;
int cpt_coup=0;
int tmp_player=firstPlayer;

while ( !positionTerminale(Pos))
{
  
   affichePosition( Pos);

   if(tmp_player%2 != 0)
   {
      printf("\nC'est à %s de jouer\n",joueur_humain.nom);

      tmp_coup=coupSaisi(Pos);
      Pos=joueLeCoup(Pos,tmp_coup);
      
   } else 
   {

      printf("\nC'est à %s de jouer\n",*joueur_ia.nom);

      tmp_coup=trouveCoupIA(Pos);
      Pos=joueLeCoup(Pos,tmp_coup);
      
   }  

  
   cpt_coup++;
   tmp_player++;


}

/**************************************************************
*

  • Affichage du gagnant

**************************************************************/

if(tmp_player % 2 != 0)
{
printf("\n\n\n L’IA a gagner ! (en %i coups)\n\n",cpt_coup–);

} else
{
printf("\n\n\n %s a gagner ! (en %i coups)\n\n",nom1,cpt_coup–);

}

}

/***************************************************************
*

  • Main ()

***************************************************************/

main() {

int position=11;

printf("\033[2J");

printf(" *********************************************\n");
printf(" * *\n");
printf(" * Bienvenu sur le jeu de Nim v1.0 *\n");
printf(" * *\n");
printf(" *********************************************\n\n");

*joueur_ia.nom=“l’IA”;
joueur_ia.nbPrises=0;

//printf("---->%s<----",*joueur_ia.nom);

printf("\nVeuillez entrer votre nom (joueur 1):\n");

scanf("%s",joueur_humain.nom);

//printf("---->%s<----",joueur_humain.nom);

printf("\n");

firstPlayer = demanderPredicat(“Voulez-vous commencer la partie ?”);

moteurIA(position);

}

[/cpp]

En tout cas merci d’avoir tout lu :stuck_out_tongue: [:matleflou]

Compile avec -ansi -Wall, au moins ça te forcera à faire du C un peu plus propre. Parce que c’est réellement crade (emacs sait indenter pourtant ? Menu edit > sélect all, puis C > indent ?)

Et dernière chose :

char *nom1[50];
char *nom2[50];

Ca, c’est pas un tableau de char (soit une chaîne C, terminée par un \0) mais un tableau de char* (soit un tableau de pointeur sur char, probablement pour des chaînes)

En somme :

*joueur_ia.nom=“l’IA”;

L’étoile porte sur nom, et est donc nécessaire parce que tu as mis char* nom[50], au lieu de char nom[50]…

euh bon je reprends :
char tab[50] est un tableau de 50 char (donc une chaine de charactère)
char* tab[50] est un tableau de 50 pointeur sur un char (donc ca peut etre une chaine de caractère mais vaut mieux pas)
ensuite

char tab[50];
tab = “test”;
ne marche pas en C.
il faut faire :
char tab[] = “test”; //je crois
ou
chat tab[50];
strcpy(tab,“test”);

Pour afficher ensuite c’est :
printf("%s\n", tab); // et pas *tab

Sinon pour ton code je te conseil vivement d’enlever toutes tes variables globales car tu vas avoir du mal à le debuger sinon (et c’est pas propre en plus).

[cpp]

char buffer[256];

strcpy(buffer,“ma chaine”); /// c comme ça et pas buffer=“ma chaine”;

[/cpp]

ffluff>

tab[] = “test”;
char tab[50] = “test”;
c’est équivalent modulo la taille du tableau dans le premier cas (c’est juste 5)

De plus,
char tab[50];
tab = “test”;

Peut fonctionner sous certains cas (mais pas cette forme) :

char *s;
s = “truc”;

fonctionne.

le seul truc qui est toleré c l’initialisation à la declaration

[cpp]

char s1[]=“chaine”;
char s1[32]=“chaine”;
char s1[3][10]={
“un”,
“deux”,
“trois”
};

[/cpp]

mais quesque vous trouver pas propre a part l indentation ?
Le code en lui meme?
pour les variables globales, les charger de td nous on conseiller de faire cela !
Pour nom1 et nom2, je les utilisent plus dans le programme, ca servait pour une version anterieur

EDit: Sous emacs j’ai indenté mais ya quelques lignes tellement grandes que ca fer crade apres [:adminofplaygroup]

Mais ca me vexe, ou plutot ca m attriste de savoir que vous trouver ca pas propre, aidez moi s’il vous plais a changer mais mauvaises habitudes :jap:

Parce que j’aime avoir raison :
[cpp]int main(void)
{
char *s;
s = “bonjour”;
}
gcc -ansi -Wall essai.c
essai.c: In function `main’:
essai.c:6: warning: control reaches end of non-void function
[/cpp]

A la base “…” c’est déjà un pointeur, et gcc te traduit ça correctement : il stocke dans la mémoire quelque part ta chaîne, et définit s à l’adresse de cette chaîne.

Le_syndicat :

Ton code n’est pas propre parce que :

  1. variables globales : les variables globales sont à éviter autant que possible. Surtout dans ton source, où Nom/Prenom doivent aller dans le main / là où tu t’en sers et pas en global.

  2. variables : toute variable doit être déclarée peu avant là où elle va être utilisée, et comme tu fais du C ANSI (c’est ce qu’on fait en licence/deug de Math info), toute déclaration doit être faite avant toute instruction. ie:

[cpp]
int main(void)
{
int x = 3;
int y;
if ( x )
{
y = 3;
}
}[/cpp]

Ceci n’est pas bon car y est utilisé seulement dans le bloc if. D’où :
[cpp]
int main(void)
{
int x = 3;
if ( x )
{
int y = 3;
}
}[/cpp]

Concernant maxou (emacs) : ça se configure. Faut faire passer tab indent à 2, et mettre Indent with space peut aider.

ça marche mais c pas une copie de chaine, c est une affectation de pointeur :slight_smile:

[cpp]
int main(void)
{
const char *s;
s = “bonjour”;
}
[/ccp]

const pour pas faire de betise de ce pointeur…

On est d’accord :slight_smile: