Voyez-vous, je butte actuellement sur le deuxième TD du cours en C, celui avec le jeu du pendu, comme ceux qui ont lu le sous-titre du sujet savent déjà. Or voyez-vous, dans la première phase de mon programme où les variables s'initialisent et où les volumes des tableaux s'ajustent à la longueur du mot à trouver, la fonction malloc, présentée dans le chapitre sur l'allocation dynamique, ne restitue pas la valeur que j'attendais d'elle, à savoir 4, qui est censée être le volume du tableau qui va devoir remplir la chaîne de caractères qui va s'afficher à l'écran et se révéler peu à peu au joueur, et qui doit être égale en longueur à la chaîne de caractères contenant le mot à trouver, lui-même. Voici la section du code en question:
int main()
{
int i, test_positif, indice_valide, quant_lettres = 0;
char lettreIndice;
char motsecret[32] = "TEST";
for (i = 0; motsecret[i] != '\0'; ++i){
quant_lettres++;
}
printf("La taille du mot est de %d caracteres.\n\n", quant_lettres);
char *motsecret_cache = NULL;
motsecret_cache = malloc(quant_lettres * sizeof(char));
printf("%s", motsecret_cache);
quant_lettres = 0;
printf("Test: nombre de cases dans motsecret_cache:\n");
for (i = 0; motsecret_cache[i] != '\0'; ++i){
quant_lettres++;
}
printf("%d", quant_lettres);
printf("%s", motsecret);
for (i = 0; motsecret_cache[i] != '\0'; ++i){
motsecret_cache[i] = '*';
}
printf("%s", motsecret_cache);
[...]
Comme vous pouvez le voir, j'ai ajouté quantité de printf afin de suivre l'action du code pendant les tests et constater clairement où se trouvent les problèmes quand ils surviennent. Quand j'exécute le programme, celui-ci renvoit les lignes suivantes sur le tableau de commandes:
La taille du mot est de 4 caracteres.
0q▬Test: nombre de cases dans motsecret_cache:
3TEST***Veuillez indiquer une lettre de votre choix:
La deuxième et la troisième ligne montrent bien que le programme ne renvoit pas la valeur de la longueur de la chaîne de caractères qui doit servir de modèle au test. Quelle peut bien en être la raison? Passez une bonne soirée, d'ici-là.
malloc ne renvoie pas une taille, ça te renvoie une adresse. Et donc ça peut varier d'un lancement à l'autre.
malloc, ça veut dire "trouve moi 4 octets". S'il te renvoie NULL c'est que ça a foiré, sinon il te renvoie l'endroit ou il a trouvé ces octets, et pas de taille. A toi ensuite de mettre ce que tu veux dedans.
Quand je dis "renvoyer une taille", je veux dire "une adresse de tableau dont le volume sera équivalent à celui de la chaîne correspondant au mot à trouver". Et je constate qu'il renvoit un tableau dont la longueur ne correspond pas à la taille que je souhaite, quand bien même j'ai veillé à indiquer la variable qui sert strictement à indiquer la longueur de la chaîne de caractère, à la fonction.
malloc te renvois bien l'adresse de ton bloc mémoire alloué et il fait bien 4 octets dans ton code ! Ce sont tes tests qui sont foireux !
Quand malloc a alloué la mémoire, il ne l'initialise pas, alors il y a n'importe quoi dedans, et toi tu essais de l'afficher comme si cela était une chaîne de caractère, forcement ça affiche n'importe quoi et tu calcules la longueur comme si cela était une chaîne de caractère, donc ça affiche n'importe quoi !
J'ai surtout essayé de transmettre la valeur de la première chaine de caractère comme indicateur pour créer un tableau de longueur correspondante. Mais je n'arrive pas à me servir de cette fonction malloc()!
@edgarjacobs: je lis "stcpy" au lieu de "strcpy" @saphintosh: edgarjacobs a voulu te montrer quelques petites choses: + il faut réserver un espace de plus pour la fin de la chaîne (ou tableau de char). (la fin de chaîne c'est le caractère '\0') + il faut recopier quelque chose dans le tableau réservé par malloc(), Ça ne s'initialise pas tout seul. (ici, c'est strcpy() qui fait la copie de l'ancienne chaîne dans la nouvelle) + on peut modifier le contenu de cette chaîne. (ici, "Je" est remplacé par "Il")
Le Tout est souvent plus grand que la somme de ses parties.
Bonjour, désolé d'avoir mis tant de temps à répondre, je perds facilement ma motivation quand j'arrive pas à faire ce que je m'étais imposé. Donc, j'ai repris le code proposé par EdgarJacobs, avec les espaces en plus et en remplaçant les noms des variables par des termes plus pertinents dans le cadre du TP. Voici ce que ça donne, dans la séquence en question:
int i, quant_lettres = 0;
char lettreIndice;
char motsecret[sizeof(int)] = "TEST";
quant_lettres = strlen(motsecret); //Je reprends le code de Edgar
printf("La taille du mot est de %d caracteres.\n\n", quant_lettres); //Je teste. La console renvoit bien la quantité de caractères dans le mot "Test"
char *motsecret_cache = malloc(quant_lettres); //J'attribue au cache qui servira à afficher les lettres déjà découvertes une adresse ainsi que la longueur du tableau qu'il aura à stocker
for (i = 0; motsecret_cache[i] != '\0'; i++){
motsecret_cache[i] = '*';
}//Je remplace les caractères du cache par un joker provisoirement jusqu'à ce que le caractère entré corresponde avec le mot secret en mémoire.
printf("%s", motsecret_cache);//Je teste
Or, en lançant le programme, j'obtiens en console la chose suivante: "La taille du mot est de 4 caractères (bon jusque-là ça se tient, puis:)
******"
6 jokers. Pourtant, je n'aurais dû avoir qu'autant de jokers qu'il n'y avait de caractères dans le mot "TEST", à savoir 4, d'autant que j'ai utilisé la fonction strlen(motsecret) pour attribuer à motsecret_cache. J'avais même essayé à la base avec un "+1" comme recommandé dans la réponse d'Edgar, mais à quoi bon ajouter un espace quand il y a déjà trop de caractères par rapport à ce que le tableau était censé stocker? Ou ai-je merdé? Merci d'avance.
Edit:
J'ai tenté de tester la longueur de la chaîne motsecret_cache avec un printf("%s", strlen(motsecret_cache)) et j'obtiens un 3. Je fais un +1 correspondant au caractère '\0' dans la chaine originale à la fonction char *motsecret_cache = malloc(quant_lettres), et voilà que j'obtiens un 2. Voilà qui n'arrange pas les choses.
Edit:
Bon oubliez ça. En fait, la solution était toute bête. Le code que j'ai envoyé n'était qu'une fraction de mon main.c. En fait, le print("%s", motsecret_cache) se répétait dans les lignes suivantes sans que je l'eus remarqué. Je vous ai dérangé pour rien, je veillerais que ce soit pour quelque chose d'utile la fois suivante.
Réponse à Magma:
Serais-ce au sujet de la confusion que j'ai eu par rapport au %d que j'ai mis à la place du %s, que je viens de corriger? Il ne s'agit pas d'une erreur d'assimilation du concept de chaîne de caractères, mais d'un oubli, dans la frustration d'avoir à retranscrire précisément ce que j'ai fais dans mon programme.
Tu n'as pas le résultat attendu car tu ne tiens pas compte de ce que l'on te dit
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char motsecret[] = "TEST"; /* on peut aussi faire char motsecret[5]
* là, on laisse le compilateur déterminer
* la bonne taille nécessaire
* ton char motsecret[sizeof(int)] n'a
* aucun sens */
int quant_lettres = strlen(motsecret);
printf("La taille du mot est de %d caracteres.\n\n", quant_lettres);
/* il faut allouer un char de plus que le nombre de lettres
* car il faut un espace additionnel pour le caractère
* terminateur '\0' */
char *motsecret_cache = malloc(quant_lettres + 1);
/* puisqu'on dispose du nombre de lettres, on s'en sert pour
* borner la boucle */
for (int i = 0; i < quant_lettres; i++) {
motsecret_cache[i] = '*';
}
printf("Mot secret : %s\n", motsecret_cache);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char motsecret[] = "TEST"; /* on peut aussi faire char motsecret[5]
* là, on laisse le compilateur déterminer
* la bonne taille nécessaire
* ton char motsecret[sizeof(int)] n'a
* aucun sens */
int quant_lettres = strlen(motsecret);
printf("La taille du mot est de %d caracteres.\n\n", quant_lettres);
/* il faut allouer un char de plus que le nombre de lettres
* car il faut un espace additionnel pour le caractère
* terminateur '\0' */
char *motsecret_cache = malloc(quant_lettres + 1);
/* puisqu'on dispose du nombre de lettres, on s'en sert pour
* borner la boucle */
for (int i = 0; i < quant_lettres; i++) {
motsecret_cache[i] = '*';
}
/* comme le rappelle markand il faut veiller à terminer
* cette chaîne également ou alternativement utiliser calloc
* au lieu de malloc, qui met à zéro l'espace mémoire alloué */
motsecret_cache[quant_lettres] = '\0';
printf("Mot secret : %s\n", motsecret_cache);
return 0;
}
Bon oubliez ça. En fait, la solution était toute bête.
Non, c'est bourré d'erreur ! Il faut que tu revois ça avant d'allé plus loin dans ton cours. Il faut même revenir en arrière !
Parce que ça commence très mal :
-
char motsecret[sizeof(int)] = "TEST";
Sais-tu ce que signifie l'opérateur sizeof ?
-
for (i = 0; motsecret_cache[i] != '\0'; i++){
motsecret_cache[i] = '*';
}
Et ici tu test le caractère de fin de chaîne pour mettre fin à la boucle, mais tu l'as mis quand dans le tableau motsecret_cache et avais-tu la place de le mettre ?
En adaptant le nom des variables à leur utilisation dans le programme. Quand au "t'as pas mis le +1", non seulement la valeur de la variable ne correspondait pas à celle qu'elle devait donner, mais je suis tombé à une valeur de 2 caractères signalés par mon code, ce qui est quand même fort. Le "+" s'est comporté comme un "-".
× 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.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
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.
git is great because Linus did it, mercurial is better because he didn't.
git is great because Linus did it, mercurial is better because he didn't.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent