Alors voilà je suis au deuxième TP sur le cours de Langage C où je dois notamment faire un pendu.
Après plusieurs tentatives, j'ai enfin réussi à lire ligne par la ligne mon fichier, enfin presque parce que là par exemple , si je pioche le mot 17, mon code prend le mot 18 :/
Voici ma fonction qui doit aller chercher le mot secret dans le fichier ( pendu.txt ) :
int choisirMot(int position,char motChoisi[])
{
FILE *pendu = NULL;
int i=0;
pendu=fopen("pendu.txt","r+");
rewind(pendu);
if (pendu==NULL)
{
printf ("Une erreur s'est produite ! \n");
return 0;
}
for (i=0;i<position;i++) // Boucle qui permet de se placer sur le bon mot
{
while (fgetc(pendu)!='\n'); // Pour chaque itération on lit tous les caractères de la ligne et on passe à la suivante
}
fgets(motChoisi,TAILLE_MAX,pendu);
}
Mais j'ai réussi à régler le problème en mettant dans la condition du for " i < (position - 1) "
Mais je comprend pas pourquoi ça a marché car si j'ai besoin par exemple du mot 15, ma boucle doit normalement lire toutes les lignes ( caractères plutôt ) jusqu'à la ligne 14 et ainsi je pourrais avec le fgets prendre le mot 15 ?
Tou dépend de ce que position indique pour le 1er mot : vaut-il 0 (zéro) ou 1 ? Si le premier mot est indiqué par 0, alors ton code est correct. Sinon, si le premier mot est indiqué par 1, alors tu dois effectivement limiter la boucle for à position-1.
- Edité par edgarjacobs 4 août 2021 à 20:44:14
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Tou dépend de ce que position indique pour le 1er mot : vaut-il 0 (zéro) ou 1 ? Si le premier mot est indiqué par 0, alors ton code est correct. Sinon, si le premier mot est indiqué par 1, alors tu dois effectivement limiter la boucle for à position-1.
- Edité par edgarjacobs il y a 18 minutes
Yo merci de ta réponse !
En effet le premier mot est indiqué par 0 ( j'ai rajouté une condition dans mon code pour que quand c'est 0 il fasse le fgets directement sinon le mot ne s'affichait pas correctement si c'est 0 )
Mais je ne comprend toujours pas en quoi si c'est 0 on doit mettre position - 1
Aha merci beaucoup de ton aide ! En effet dans vscode je voyais que le mot était sur la ligne 1 ce qui m'a induit en erreur
Merci aussi pour la fin en effet quand je testais un srtlen sur le mot ça me donnait un chiffre au dessus de la taille exacte du mot ( par exemple pour chat strlen me renvoyait 5 ) j'ai oublié le '\n'
Merci encore je passe en résolu
EDIT : [ Mais du coup pourquoi mettre 0 ? J'aurais pu mettre n'importe quel chiffre vu que c'est une chaine que je veux à la base ? ]
Comment faire pour que la position du premier mot soit 1 et non 0 ?
EDIT 2 : j'avais aussi une question qui me taraude depuis pas mal de temps : si je crée un tableau de char de taille 100, le '\0' symbolisant la fin de la chaine se trouve t'il à la 100ème position ? Si je met dans ce tableau le mot " chat " , le '\0' se place t'il alors en 5ème position ou bien reste t'il toujours à la 100 ème position ( si c'est le cas ) ?
EDIT 3 : Dans mon code, à quel moment fgets prend le '\n' ? Car en supposant que la position du 1er mot est la position 1, si le mot que je veux est le 4ème mot, fgetc prendra le '\n' de la fin de la ligne du troisième mot ( d'après la condition ( while(fgetc(fichier)!='\n' )
si je crée un tableau de char de taille 100, le '\0' symbolisant la fin de la chaine se trouve t'il à la 100ème position ?
Qu'est-ce que tu entends par « 100ème position » ? Il faut être précis (et alors tout devient plus compréhensible). Avec les tableaux, je te suggère de parler d'indice. Mais je crois que tu parles de l'indice 99. Donc tu demandes si, lorsqu'on déclare un tableau char[100], un '\0' est mis automatiquement à l'indice 99. Réponse : non. Si on initialise la chaîne de caractère, un '\0' est mis juste après les caractères de la chaîne, donc en indice 4 pour "chat". Si on ne fait pas d'initialisation, on a juste réservé 100 cases mémoire pour y mettre des caractères, mais pour l'instant elles contiennent n'importe quoi.
(C'est vrai que ce serait judicieux que le système ajoute un octet avec le caractère nul, ainsi on n'aurait jamais de dépassement. Mais je crois qu'en C, un octet est un octet, on ne va pas en gaspiller...)
si je crée un tableau de char de taille 100, le '\0' symbolisant la fin de la chaine se trouve t'il à la 100ème position ?
Qu'est-ce que tu entends par « 100ème position » ? Il faut être précis (et alors tout devient plus compréhensible). Avec les tableaux, je te suggère de parler d'indice. Mais je crois que tu parles de l'indice 99. Donc tu demandes si, lorsqu'on déclare un tableau char[100], un '\0' est mis automatiquement à l'indice 99. Réponse : non. Si on initialise la chaîne de caractère, un '\0' est mis juste après les caractères de la chaîne, donc en indice 4 pour "chat". Si on ne fait pas d'initialisation, on a juste réservé 100 cases mémoire pour y mettre des caractères, mais pour l'instant elles contiennent n'importe quoi.
(C'est vrai que ce serait judicieux que le système ajoute un octet avec le caractère nul, ainsi on n'aurait jamais de dépassement. Mais je crois qu'en C, un octet est un octet, on ne va pas en gaspiller...)
- Edité par robun il y a 12 minutes
Merci de ta réponse !
Ah oui je parlais bien de l'indice 99 c'est vrai que ça peut porter à confusion
Mais si sans initialisation un tableau de 100 char contient " n'importe quoi " , si j'y met le mot chat , c'est donc tout ce qui était dans la chaine qui est effacé puis le char est "inclus" d'où le '\0' qui vient se mettre après ? Parce que si j'écrase seulement les cases nécessaires à la saisie du mot " chat " , le reste contenant n'importe quoi , comment le '\0' peut 'il venir après " chat " ? que contiennent les autres cases alors ?
fgets(var,size,file) lit file et remplit var jusqu'à ce que soit un \n soit rencontré (qui est aussi mis dans var), soit que size-1 caractères ait été lus (voir ici)
En fait, en mémoire, "chat" est écrit 'c' 'h' 'a' 't' '\0'. Si tu fais un strcpy(var,"chat"), strcpy() copie tous les caractères à partir du 'c' de "chat" jusque et y compris le '\0' qui suit le 't' de "chat". Et si var au départ contenait n'importe quoi, hé bien les indices 5 à 99 (dans le cas de char var[100]) contiennent toujours n'importe quoi.
- Edité par edgarjacobs 5 août 2021 à 18:22:08
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
fgets(var,size,file) lit file et remplit var jusqu'à ce que soit un \n soit rencontré (qui est aussi mis dans var), soit que size-1 caractères ait été lus (voir ici)
En fait, en mémoire, "chat" est écrit 'c' 'h' 'a' 't' '\0'. Si tu fais un strcpy(var,"chat"), strcpy() copie tous les caractères à partir du 'c' de "chat" jusque et y compris le '\0' qui suit le 't' de "chat". Et si var au départ contenait n'importe quoi, hé bien les indices 5 à 99 (dans le cas de char var[100]) contiennent toujours n'importe quoi.
- Edité par edgarjacobs il y a 18 minutes
Merci beaucoup je comprend beaucoup mieux maintenant ! Je trouve mieux d'utiliser fgets directement
Bon dernier problème ( ) , j'ai une fonction qui prend en paramètre le mot choisi, le caractère que le joueur a entré ainsi que la chaine du mot choisi qui est cachée pour le coup ( dans cette chaine, on a des '*' )
Mais on dirait que ça marche que lors de la première itération dans mon main ( j'ai utilisé un do - while pour la boucle de lecture/verification des caractères ) . Cette fonction me renvoie 1 si tout s'est bien passé ( le caractère est bien dans le mot choisi et il l'a remplacé dans la chaine caché ) et 0 si le caractère n'y est pas .
Problème : Si le mot est par exemple chat , la fonction me renvoie 1 que pour le ' C ' et pour toutes les autres lettres elle me renvoie 0
Voici la fonction :
int verif_Replace(char motChoisi[],char caractereSaisi,char motChoisiCache[])
{
int i=0;
if ((strchr(motChoisi,caractereSaisi)!=NULL))
{
for (i=0;i<strlen(motChoisi);i++)
{
if (motChoisi[i]==caractereSaisi)
{
motChoisiCache[i]=caractereSaisi;
}
}
return 1;
}
return 0;
}
Ta fonction me semble correcte. Montre ton programme, le problème vient sans doute d'ailleurs.
Voici le programme au complet :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "pendu.h"
#define TAILLE_MAX 50
int main()
{
char caractereSaisi = 0;
int positionAleatoire=0,tentativesRestantes=10,nombreDemots = 0,reponse=0,valeurDeRetour=0;
const int min=1;
char motChoisi[TAILLE_MAX]="",motChoisi_Cache[TAILLE_MAX]="";
do
{
tentativesRestantes=10;
nombreDemots=nombreMots();
if (nombreDemots==0)
{
printf ("Une erreur s'est produite ! \n");
return 0;
}
srand(time(NULL));
positionAleatoire=(rand() % (nombreDemots - min + 1)) + min;
if (choisirMot(positionAleatoire,motChoisi)==0)
{
printf ("Une erreur s'est produite !\n");
return 0;
}
miseAetoile(motChoisi_Cache,motChoisi);
printf ("\nBienvenue au jeu du Pendu !\n");
do
{
printf ("\nIl vous reste %d coups a jouer !\n",tentativesRestantes);
printf ("Quel est le mot mystere ? %s\n",motChoisi_Cache);
printf ("Proposez une lettre : ");
caractereSaisi = lireCaractere();
valeurDeRetour = verif_Replace(motChoisi,caractereSaisi,motChoisi_Cache);
if (valeurDeRetour==0)
{
tentativesRestantes--;
}
} while (tentativesRestantes!=0 && (strcmp(motChoisi,motChoisi_Cache))!=0);
if (tentativesRestantes==0)
{
printf ("\nPlus de tentatives restantes ! C'est perdu ^^\n");
printf ("Voulez vous reessayer ? \n[ TAPEZ 1 POUR REESSAYER ET 0 POUR ARRETER ] : ");
scanf ("%d",&reponse);
}
else
{
printf ("Bravo ! %s etait bien le mot mystere ^^",motChoisi_Cache);
printf ("Voulez vous faire une nouvelle partie ? \n[ TAPEZ 1 POUR REESSAYER ET 0 POUR ARRETER ] : ");
scanf ("%d",&reponse);
}
} while (reponse==1);
return 0;
}
char lireCaractere()
{
char c = 0;
c = getchar();
c = toupper(c); // Mettre le caractère en majuscule
while(getchar() != '\n'); // Le ';' est là pour remplacer les {}
return c;
}
void miseAetoile(char motCache[],char motChoisi[])
{
int i=0;
strcpy(motCache,motChoisi);
for (i=0;i<(strlen(motCache));i++)
{
motCache[i]='*';
}
}
int nombreMots()
{
FILE *pendu = NULL;
char temp[TAILLE_MAX]="";
int cpt=0;
pendu=fopen("pendu.txt","r");
rewind(pendu);
if (pendu==NULL)
{
printf ("Une erreur s'est produite ! \n");
return 0;
}
while (fgets(temp,TAILLE_MAX,pendu)!=NULL)
{
cpt++;
}
fclose(pendu);
return cpt;
}
int choisirMot(int position,char motChoisi[])
{
FILE *pendu = NULL;
int i=0;
char *clean=NULL;
pendu=fopen("pendu.txt","r+");
if (pendu!=NULL)
{
rewind(pendu);
for (i=0;i<position;i++) // Boucle qui permet de se placer sur le bon mot
{
fgets(motChoisi,TAILLE_MAX,pendu);
}
fclose(pendu);
clean = strchr(motChoisi,'\n');
if (clean != NULL)
{
*clean=0;
}
return 1;
}
else
{
return 0;
}
}
int verif_Replace(char motChoisi[],char caractereSaisi,char motChoisiCache[])
{
int i=0;
if ((strchr(motChoisi,caractereSaisi)!=NULL))
{
for (i=0;i<strlen(motChoisi);i++)
{
if (motChoisi[i]==caractereSaisi)
{
motChoisiCache[i]=caractereSaisi;
}
}
return 1;
}
return 0;
}
Une piste: en C, 'A' et 'a' sont deux caractères différents
Tu devrais pouvoir trouver d'où vient le problème....
- Edité par edgarjacobs il y a environ 1 heure
HAHA je viens de comprendre ( en vrai je connaissaient déjà le code ascii on l'a fait cette année en dut )
La fonction lireCaractere, je l'avait prise sur le cours de langage C j'avais remarqué que ça mettait les lettres en maj sans y prêter plus grande attention
En tout cas merci infiniment pour le temps que t'as consacré à m'aider !!! ( Pour te remercier, je reviendrais bientôt sur un autre programme avec de nouveaux problèmes rencontrés... )
EDIT : ça fonctionne très bien maintenant merci encore
Je reprend cette ligne: for (i=0;i<position;i++) Si la première ligne est désignée par 0, c'est correct. Sinon, si la première ligne est désigné par 1, il faut faire: for (i=1;i<position;i++)
Le Tout est souvent plus grand que la somme de ses parties.
Lire ligne par ligne un fichier
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Le Tout est souvent plus grand que la somme de ses parties.