logo Homepage
+  NewbieContest
|-+  Programmation» Langages compilés» [C] Problème avec un Pendu...
Username:
Password:
Pages: [1] 2
  Imprimer  
Auteur Fil de discussion: [C] Problème avec un Pendu...  (Lu 12274 fois)
Edurion

Profil challenge

Classement : 11366/54285

Néophyte
*
Hors ligne Hors ligne
Messages: 13


Voir le profil
« le: 12 Février 2008 à 11:39:57 »

Bonjour à tous!

Je vous explique rapidement mon problème: J'ai décidé, il y a déjà plusieurs semaines, de coder un pendu pour quelqu'un. Pas très intéressant, certes, mais je me suis dis qu'avant de me lancer dans l'algorythmique, les sockets et autres, je ferais bien de maitriser les bases. J'ai donc créé le jeu, sans gestion du dictionnaire, il marchait sans problème. Mais maintenant que cette dernière est arrivée, le programme rencontre un petit problème... Il y a plusieurs hypothèse, qui vous paraîtront évidentes avec le code sous les yeux, mais je vais déjà vous les donner:

-Soit le programme n'affiche pas les lettres trouvées.
-Soit il ne les reconnait pas (plus embêtant...)
-Soit il ne lit pas la lettre entrée par l'utilisateur... (je n'ai pas utilisé de scanf)

Le code n'est sûrement pas optimisé, mais pour l'instant, je m'interesse tout simplement à son bon fonctionnement.

Je dois aussi préciser que certaines idées - notamment la non-utilisation du scanf - ne sont pas de moi, mais viennent du Site du Zero.

Trêve de bavardage, et passons au code:

Code: (C)
/*
Jeu du Pendu réalisé par Edurion
Version numéro: 1.0
Gestion du dictionnaire incluse
Copyright 2008
Toutes modification sans l'accord du dévellopeur est à proscrire
*/

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>

int PiocherMot(char *motPioche,FILE* dico);
int nombreAleatoire(int nombreMot);

char LireCaractere();
int RechercheLettre(char lettreEntree, char motSecret[], int lettreTrouvee[]);
void perror (const char *s);
int main(int argc, char argv[])
{
    int choix, choix2, boucle, coupsRestant=11, i, arrete=0, gagne=0;
    char lettreEntree, motPioche;
    FILE* dico = NULL;
    dico = fopen("dico.txt", "r");
    char motSecret[100]={0};
    char* s=NULL;
    int lettreTrouvee[100]={0};
    int nombreLettre=0;

    do
    {

    printf("\n                        -=-=-=-=-=-Bienvenue sur le Pendu!-=-=-=-=-=-\n");
    printf("\n\n   -=} 1 - Demarrer le jeu (1J){=-");
    printf("\n   -=} 2 - Demarrer le jeu (2J & +) {=-");
    printf("\n   -=} 3 - Rajouter un mot dans le dictionnaire {=-");
    printf("\n   -=} 4 - Quitter {=-\n");
    scanf("%ld", &choix);

    switch (choix)
    {
        case 1:
        perror(s);


        if(PiocherMot(motSecret, dico)==0)
        {
            boucle=0;
            perror(s);
        }
        else
        {
                printf("                  --=Vous avez choisi le mode 1 joueur=--!\n\n");
                nombreLettre = strlen(motSecret);
                printf("Le mot a trouver est un mot de %ld lettres!\n", nombreLettre);

                coupsRestant=11;
                arrete=0;
                int lettreTrouvee[100]={0};
                gagne=0;

            do
            {
                if(gagne==1)
                {
                    printf("Bravo! Vous avez gagne!\n");
                    printf("Le mot a trouver etait bien %s !\n\n", motSecret);
                    fclose(dico);
                    arrete=1;
                }
                else if(coupsRestant==0)
                {
                    //Code de la défaite
                    printf("Desole, vous avez perdu!\n");
                    fclose(dico);
                    arrete=1;
                }
                else
                {
                for(i=0; motSecret[i] != '\0'; i++)
                {
                    if(lettreTrouvee[i])
                    {
                        printf("%c", motSecret[i]);
                    }
                    else
                    {
                        printf("*");
                    }
                }
                printf("\nIl vous reste %ld coups a jouer!\nProposez une lettre...", coupsRestant);
                lettreEntree = LireCaractere();
                if(!RechercheLettre(lettreEntree, motSecret, lettreTrouvee))
                {
                    coupsRestant--;
                }

                printf("\n\n\n\n");
                for(i=0; motSecret[i] != '\0'; i++)
                {
                    gagne=0;
                    if(lettreTrouvee[i] == 1)
                    {
                        gagne++;
                    }
                    else
                    {
                        gagne--;
                    }
                }
                if(gagne==nombreLettre)
                {
                    gagne=1;
                }
                else
                {
                    gagne=0;
                }
                }
        }while(arrete==0);
        fclose(dico);
        printf("Voulez-vous refaire une partie?\n");
        printf("1 - Oui\n2 - Non\n");
        scanf("%ld", &boucle);
        }
        break;
        case 2:
        //Code 2 joueur
        printf("pas encore");
        boucle=1;
        break;
        case 3:
        //Mode d'ajout
        printf("pâtience");
        boucle=1;
        break;
        case 4:
        printf("\n\n\n\t\a Voulez-vous vraiment quitter?\n\n");
        printf("1 - Oui\n2 - Non\n");
        scanf("%ld", &choix2);

        if(choix2==1)
        {
            boucle=0;
        }
        else
        {
            boucle = 1;
        }
        break;
    }
    }while(boucle==1);

return 0;

}

int RechercheLettre(char lettreEntree, char motSecret[], int lettreTrouvee[])
{
    int i=0;
    int bonneLettre = 0;
    for(i=0; motSecret[i] != '\0'; i++)
    {
        if(lettreEntree == motSecret[i])
        {
            bonneLettre = 1;
            lettreTrouvee[i]=1;
        }
    }
    return bonneLettre;
}



char LireCaractere()
{
    char caractere = 0;

    caractere = getchar(); // On lit le premier caractère
    caractere = toupper(caractere); // On met la lettre en majuscule si elle ne l'est pas déjà

    // On lit les autres caractères mémorisés un à un jusqu'à l'\n (pour les effacer)
    while (getchar() != '\n') ;

    return caractere; // On retourne le premier caractère qu'on a lu

}



int nombreAleatoire(int nombreMot)
{
    srand(time(NULL));
    return (rand() % nombreMot);
}




int PiocherMot(char motSecret[],FILE* dico)
{
    int caractereLu=0, nombreMot=0, numeroMotChoisi=0;
    if(dico==NULL)
    {
        printf("Le fichier du dictionnaire n'a pas pu etre charge...");
        return 0;
    }

        do
        {
            caractereLu=fgetc(dico);
            if(caractereLu == '\n')
            {
                nombreMot++;
            }
        }while(caractereLu != EOF);

        numeroMotChoisi = nombreAleatoire(nombreMot);

        rewind(dico);
        while(numeroMotChoisi > 0)
        {
            caractereLu = fgetc(dico);
            if(caractereLu == '\n')
            {
                numeroMotChoisi--;
            }
        }
        fgets(motSecret, 100, dico);
        motSecret[strlen(motSecret) - 1] = '\0';
        return 1;
}



Voila!

Vous remarquerez que seuls le mode 1 joueur est disponible, les autres découlant du premier, je les rajouterais après sans problème, je pense.

Je vous rappelle une dernière fois que mon but n'est pas, pour l'instant, d'optimiser mon code et de le simplifier, sauf si bien sur cela est nécessaire à son fonctionnement!

Dans tous les cas, je vous remercie d'avance pour l'attention que vous porterez à mon message, et vous souhaite une excellente semaine!

Edurion

P.S.: Je viens de le voir en prévisualisation, mais ne prêtez pas attention aux quelques perror, c'était juste pour essayer de cerner le problème... Pour info: Ils renvient tous "no error"
Journalisée
_o_
Relecteur

Profil challenge

Classement : 42/54285

Membre Héroïque
*
Hors ligne Hors ligne
Messages: 1258


Voir le profil
« #1 le: 12 Février 2008 à 19:32:37 »

Je vous rappelle une dernière fois que mon but n'est pas, pour l'instant, d'optimiser mon code et de le simplifier, sauf si bien sur cela est nécessaire à son fonctionnement!

Bon, franchement, ne le prend pas mal, mais ça me parait une mauvaise idée. Je ne dis pas qu'il est simple d'écrire rapidement du code optimisé, surtout lorsque l'on débute, mais d'une manière générale, il vaut mieux tout de suite écrire du code propre et rapide. Parce que sinon... hé bien, il y a une probabilité non négligeable que ce ne soit jamais fait : comment se motiver à recoder un truc qui marche ? Et c'est une habitude à prendre en particulier avant d'arriver dans un environnement professionnel, ou là, on a rarement l'occasion de reprendre le code (sauf quand c'est devenu une telle horreur que le fonctionnement en pâtit, mais là, ça coûte très cher !).

Je ne répondrais pas à ta question de dysfonctionnement, mais je vais faire quelques remarques sur ton code. Tu en fais ce que tu veux.

- d'abord, je n'ai pas bien compris quel est ton problème. Tu cites des symptômes, mais ce serait intéressant que tu donnes des pistes pour les reproduire. Personnellement, je ne me sens pas (en ce moment), de jouer pendant une demi-heure avec le jeu pour tomber sur les problèmes.
- ensuite, il manque deux ou trois petites choses dans ton explication. Par exemple le format du fichier dictionnaire. On doit pouvoir le retrouver en lisant le code, mais si tu donnais la spécification du fichier, ça pourrait montrer des bugs.
- ton code manque de structure et de commentaires. La fonction main est vraiment trop longue. Et on ne sait pas à quoi servent les autres fonctions et les variables en tout genre. Bien sûr, on peut le deviner, mais c'est du temps perdu, quelque part, étant donné que tu sais toi, à quoi elles servent.
- tu ne testes pas les codes retour, et ça c'est très mal. On le voit en particulier à l'ouverture du dictionnaire : il n'y a pas de traitement d'erreur.
- je ne sais pas quel compilateur et quel système d'exploitation tu utilises, mais en l'occurrence, mon gcc configuré en Full warning (-Wall) crache pas mal d'injures (mais compile quand même). Méfiance, en général ces warnings reflètent des problèmes potentiels qui pourraient bien se finir en bug. En principe, on compile avec -Wall et on ne lance pas le bazar tant que tous les warnings n'ont pas disparu.
- tu n'utilises pas system("PAUSE") et ça, c'est très bien et je t'en remercie !!! (marre de ces habitudes idiotes ).

Bref, plus quelques petits détails dans le traitement des chaînes et ce qui semble être des tableaux de booléens, mais je vais éviter d'être trop casse-pied, et ce message commence à devenir (très) long.

Donc voilà, tu fais ce que tu veux de mes critiques, mais en tout état de cause, j'ai du mal à me mettre dans ce genre de code tant que toutes ces petites remarques sont valables. Je plaide les circonstances atténuantes : j'ai fait ce genre de choses toute la journée durant, j'ai le droit de faire une pause ce soir.

Bon courage pour la suite.
« Dernière édition: 12 Février 2008 à 19:38:58 par _o_ » Journalisée

Les épreuves de hack de NC sont trop faciles ? Et pourtant ! Bienvenue dans la vraie vie : http://thedailywtf.com/Articles/So-You-Hacked-Our-Site!.aspx
Edurion

Profil challenge

Classement : 11366/54285

Néophyte
*
Hors ligne Hors ligne
Messages: 13


Voir le profil
« #2 le: 12 Février 2008 à 20:56:33 »

Je vais répondre un par un à tes commentaires, qui, cela dit en passant, ne peuvent que m'aider à m'améliorer, et que donc je prendrai en compte.

Citation
d'abord, je n'ai pas bien compris quel est ton problème. Tu cites des symptômes, mais ce serait intéressant que tu donnes des pistes pour les reproduire. Personnellement, je ne me sens pas (en ce moment), de jouer pendant une demi-heure avec le jeu pour tomber sur les problèmes.

Un peu plus clairement: Le code est censé m'afficher les lettres trouvées (ou non) sous cette forme: ****E**R***T etc...

Or, il ne m'affiche que des *

Citation
ensuite, il manque deux ou trois petites choses dans ton explication. Par exemple le format du fichier dictionnaire. On doit pouvoir le retrouver en lisant le code, mais si tu donnais la spécification du fichier, ça pourrait montrer des bugs

C'est un simple fichier *.txt

Citation
ton code manque de structure et de commentaires. La fonction main est vraiment trop longue. Et on ne sait pas à quoi servent les autres fonctions et les variables en tout genre. Bien sûr, on peut le deviner, mais c'est du temps perdu, quelque part, étant donné que tu sais toi, à quoi elles servent.

La fonction main est peut-être trop grande, mais as-tu p^ris en compte le switch? Et si oui, comment puis-je la réduire? Quant aux noms des fonctions, je pensent qu'ils sont assez éloquents... Tout comme le nom des variables... Par exemple: PiocherMot... ou lettreEntree... Je ne pense pas changer quoi que ce soit de ce point de vue.

Citation
tu ne testes pas les codes retour, et ça c'est très mal. On le voit en particulier à l'ouverture du dictionnaire : il n'y a pas de traitement d'erreur.

Pardonne moi, mais le traitement d'erreur est bien la... Dans la fonction PiocherMot, mais je suis d'accord, j'aurais du le mettre avant...

Citation
e ne sais pas quel compilateur et quel système d'exploitation tu utilises, mais en l'occurrence, mon gcc configuré en Full warning (-Wall) crache pas mal d'injures (mais compile quand même). Méfiance, en général ces warnings reflètent des problèmes potentiels qui pourraient bien se finir en bug. En principe, on compile avec -Wall et on ne lance pas le bazar tant que tous les warnings n'ont pas disparu.

Je "travail" avec CodeBlocks. Tous les messages qu'ils m'envoient sont de toute façon à corriger, puisque sinon ça ne marche pas... Cela explique aussi ta dernière remarque, puisque CodeBlocks inclue dirrectement une pause à la fin du programme...

Enfin, je viens de corriger quelques trucs, notamment deux fclose inutiles, suite à la lecture d'un de tes posts ailleurs sur le forum, et si tu as des conseils pour l'optimisation, bien que cela ne soit pas une priorité (je dois finir le code assez vite..), je te promets qu'ils seront pris en compte! Ne serait-ce que dans les versions du pendu qui suivront, et qui permettront le jeu deux joueurs et l'ajout de mots.

Sur ce, encore merci pour les conseils!
Journalisée
Zmx

Profil challenge

Classement : 71/54285

Membre Héroïque
*****
Hors ligne Hors ligne
Messages: 559


Voir le profil WWW
« #3 le: 12 Février 2008 à 21:02:53 »

Citation
ensuite, il manque deux ou trois petites choses dans ton explication. Par exemple le format du fichier dictionnaire. On doit pouvoir le retrouver en lisant le code, mais si tu donnais la spécification du fichier, ça pourrait montrer des bugs

C'est un simple fichier *.txt
J'pense que ça suffit pas trop.
Dire que c'est un mot par ligne (par exemple) et que spécifié (enventuelement) l'encodage/les retour chariot.
Journalisée

Edurion

Profil challenge

Classement : 11366/54285

Néophyte
*
Hors ligne Hors ligne
Messages: 13


Voir le profil
« #4 le: 12 Février 2008 à 21:45:39 »

Je précise donc, le fichier contient des mots listés un à un avec un retour de chariot à la fin de chaque mots, afin de pouvoir les compter.
Journalisée
_o_
Relecteur

Profil challenge

Classement : 42/54285

Membre Héroïque
*
Hors ligne Hors ligne
Messages: 1258


Voir le profil
« #5 le: 12 Février 2008 à 21:56:41 »

Un peu plus clairement: Le code est censé m'afficher les lettres trouvées (ou non) sous cette forme: ****E**R***T etc...
Or, il ne m'affiche que des *

C'est dans ces cas là qu'il commence à être intéressant d'apprendre à se servir d'un débugger (je suppose que CodeBlocks en inclut un), et d'exécuter pas à pas le programme pour voir un peu le contenu des variables en temps réel. Ça permet de voir par exemple que (dans mon cas), le tableau lettreTrouvee est toujours rempli de... zéros. Ah mais ! Au fait, mon dictionnaire ne contient que des mots écrits en minuscule, et le tien ? Oui, tu as aussi oublié de le préciser (et j'avoue que je n'aurais pas pensé non plus à te le demander, au départ). Et pourtant cela a son importance, ici...

Bon, il y a d'autres choses, que je n'ai pas creusées. Par exemple, la détection de lettres trouvées ne fonctionne pas au premier tour. Et aussi qu'on a du mal à gagner (y'a une variable gagne qui a tendance à être souvent remise à 0). Etc. Avec un bon debugger, ça va vite de voir ce que se passe... Le tout c'est de comprendre le principe.

Citation de: Edurion
La fonction main est peut-être trop grande, mais as-tu p^ris en compte le switch? Et si oui, comment puis-je la réduire?


La présence du switch ne change pas grand chose. En gros, une fonction ne devrait pas faire plus de 20 ou 30 lignes. Il y a des outils d'audit de code qui sortent ce genre de statistiques et quand les indicateurs sont utilisés par le service qualité de la boite... on se fait taper sur les doigts. Non, c'est surtout un principe de base pour faciliter la relecture et la maintenabilité. C'est aussi valable pour la personne qui a codé : dans 3 mois tu auras peut-être du mal à te relire.

Pour améliorer, il suffit de décomposer. Par exemple, le cas du switch : je suppose que chaque case déclenche un traitement. Pourquoi ne pas écrire une fonction par traitement ? Du coup, par exemple, tu vas écrire une fonction qui permet de jouer (dans le case 1). Au final, quand tu cherches un bug dans le jeu, tu n'as pas à essayer de t'y retrouver dans le switch.

Citation
Quant aux noms des fonctions, je pensent qu'ils sont assez éloquents... Tout comme le nom des variables... Par exemple: PiocherMot... ou lettreEntree... Je ne pense pas changer quoi que ce soit de ce point de vue.


Essaie de lire du code non commenté écrit par quelqu'un d'autre et tu vas rapidement comprendre. Ce que je veux dire, c'est que par exemple, tu as le droit de mettre un commentaire avant la fonction PiocherMot pour expliquer... qu'elle choisi un mot au hasard dans le dictionnaire et qu'elle retourne... Elle retourne quoi au fait ? En particulier quand il y a une erreur ? Etc...

Autre exemple : ton tableau lettreTrouvee[]. Ça ne coûte rien de mettre un petit commentaire pour expliquer que c'est un masque, correspondant au motSecret[], dont les valeurs correspondent au fait qu'elles ont été devinées par le joueur. Ah tiens, d'ailleurs, une lettre devinée par l'utilisateur, c'est 1 ou 0 ? (ou 0xff, d'ailleurs, pourquoi pas ?).

Bien sûr, je peux répondre moi même à ces questions, mais ça me demande un peu d'analyse. En l'occurrence, ça peut décourager ceux qui voudraient t'aider à debugger. Comme c'est un peu mon cas ce soir.

Citation
Je "travail" avec CodeBlocks. Tous les messages qu'ils m'envoient sont de toute façon à corriger, puisque sinon ça ne marche pas... Cela explique aussi ta dernière remarque, puisque CodeBlocks inclue dirrectement une pause à la fin du programme...


Aaaaargh ! Je comprends mieux les horreurs que j'ai pu voir. En fait, le réglage par défaut des compilateurs (et CodeBlocks ne doit pas faire exception) est de cacher les avertissements. Autrement dit, tu as été obligé de corriger tout ce qui empêchait de compiler, mais ce n'est pas pour autant que le code est nickel. J'ai déjà demandé à quelqu'un comment faire pour que CodeBlocks affichent les avertissement, et je ne me souviens pas avoir eu de réponse. Mais c'est pourtant une excellente habitude à avoir : je ne compte plus le nombre de fois où, après un segmentation fault ravageur, je me suis rendu compte après coup que le compilo m'avait prévenu d'un truc bizarre avec un avertissement.

Voilà ce que ça donne chez moi, par exemple :
Code:
test.c:23: warning: second argument of 'main' should be 'char **'
test.c: In function 'main':
test.c:41: warning: format '%ld' expects type 'long int *', but argument 2 has type 'int *'
test.c:58: warning: format '%ld' expects type 'long int', but argument 2 has type 'int'
test.c:94: warning: format '%ld' expects type 'long int', but argument 2 has type 'int'
test.c:127: warning: format '%ld' expects type 'long int *', but argument 2 has type 'int *'
test.c:143: warning: format '%ld' expects type 'long int *', but argument 2 has type 'int *'
test.c:30: warning: unused variable 'lettreTrouvee'
test.c:25: warning: unused variable 'motPioche'

Bon, rien de bien méchant en l'occurrence.

Citation
Enfin, je viens de corriger quelques trucs, notamment deux fclose inutiles [...]

Ce que je te propose, c'est de mettre ton code sur un outil de partage, style pastebin (http://pastebin.com/). D'abord parce que c'est assez galère de lire le code affiché dans les messages ici, et ensuite parce que ça permettrait de voir les évolutions successives, et de te proposer directement des versions corrigées et/ou améliorées.

Sur ce, je range le clavier pour ce soir, j'ai largement dépassé mon quota de lettres tapées pour aujourd'hui.
« Dernière édition: 12 Février 2008 à 22:04:57 par _o_ » Journalisée

Les épreuves de hack de NC sont trop faciles ? Et pourtant ! Bienvenue dans la vraie vie : http://thedailywtf.com/Articles/So-You-Hacked-Our-Site!.aspx
Edurion

Profil challenge

Classement : 11366/54285

Néophyte
*
Hors ligne Hors ligne
Messages: 13


Voir le profil
« #6 le: 13 Février 2008 à 10:27:15 »

Tout d'abord: MERCI!

Merci pour tous les conseils avisés que tu m'as donnés! Je les suivraient bien entendus!

Je vais de ce pas mettre mon compo en mode full warnings, et modifier un peu mon code! Pour la fonction main, le message est passé!

Tu viens aussi de me montrer qu'apprendre les bases de la programmation n'est pas seulement savoir utiliser les fonctions les plus employées, mais savoir programmer, tout simplement, avec les bons outils et de bonne rigueur. Et pour cela encore je te remercie!

Je reposterai le code final, de cette façon, vous pourrez me dire ce qu'il faut changer!

Sur ce, bonne continuation à tous!

Edurion
Journalisée
mogg41

Profil challenge

Classement : 449/54285

Membre Senior
****
Hors ligne Hors ligne
Messages: 267

Mogg41 pour vous aider!


Voir le profil
« #7 le: 13 Février 2008 à 14:28:01 »

Bonjour voila 2-3 petites choses que tu pourrais changer. Cela ne corrigera pas tes erreurs de logique mais pourra t'aider  à coder plus proprement.

1- Tu pourrais découper ton code en 3 fichiers (c'est le minimum). Je m'explique:
      - Un fichier main.c ou tu écris ton main.
      - Un fichier fonction.c ou tu écris TOUTES tes fonctions (tu peux trouver un nom plus parlant).
      - Un fichier librairie.h où tu définis tes variables globales, tableaux... Tu y déclares aussi les fonctions.
      Ton projet sera composé de ton fichier main.c et de fonction.c . Tu incluras ta bibliothèque.h au début de ton main et de ton fichier fonction (# include "librairie.h).

2-
Citation
srand(time(NULL));
    Il est préférable d'initialiser ta fonction srand() qu'une seule fois. Tu peux donc la déclarer dans librairie.h .

3- Ta mise en page: Comme il a été dit cela manque de commentaires. N'hésite pas avant chaque fonction d'écrire un commentaire dans le genre (c'est ce que tu fais en algo normalement)
Code:
// Nom de la fonction
//Quels sont les paramètres
//Quel est le retour
//Quel est le traitement
//

N'hésite pas à sauter plusieurs lignes entre chaque fonction. Si tu estimes qu'une fonction est longue tu peux sauter des lignes pour la rendre moins compacte. Cela fait toujours du bien à nos petits yeux .

Un point positif: Tu marques bien les tabulations à chaque boucle, if ...


Pour ce qui est de tes problèmes logiques je n'est pas le courage de chercher car je suis en overdose de c en ce moment.


J'espère que ces remarques t'aideront à coder plus proprement. Ce sont des habitudes qu'il faut prendre le plus tôt possible. Tout le monde y est passé.

Sur ce, bon courage et bonne chance pour ton programme.

Mogg41
Journalisée

"Il ne savait pas que c'était impossible alors il l'a fait." Mark Twain
Edurion

Profil challenge

Classement : 11366/54285

Néophyte
*
Hors ligne Hors ligne
Messages: 13


Voir le profil
« #8 le: 13 Février 2008 à 15:03:34 »

Quand _o_ m'a dit que ma fonction main était trop grande, et que je devais faire plusieurs fonction, je me suis dit: fait plusieurs .c, sinon le main.c regorgera de fonction et on devra tout le temps faire des aller-retour pour lire le code... Je le ferais sur les prochaines versions!

Pour la tabulation, CodeBlocks est bien pour cela! Au moins, le code est clair et aéré!

Tes conseils seront pris en compte! Et du point de vue logique, maintenant, le code marche! La seule chose que je n'ai pas trouvée, c'est l'histoire du RechercheLettre qui ne marche jamais du premier coup... Mais je cherche, je cherche!

Par contre, _o_, pourrais-tu me donner le nom de ton compo? Je n'arrive pas à mettre CodeBlocks en full warning...

Merci d'avance!
Journalisée
Folcan

Profil challenge

Classement : 509/54285

Membre Héroïque
*****
Hors ligne Hors ligne
Messages: 1520


Voir le profil
« #9 le: 13 Février 2008 à 17:29:33 »

mon gcc configuré en Full warning (-Wall) crache pas mal d'injures (mais compile quand même).

Sans vouloir répondre à sa place...
Journalisée

-=[FoLc@N]=-

Citation :
* Le futur appartient à ceux qui croient à la beauté de leurs rêves, je crois au miens, NewbieContest aura un bon futur.
* Il y'a seulement 10 categories de gens dans la vie : ceux qui comprennent le binaire, et les autres.
_o_
Relecteur

Profil challenge

Classement : 42/54285

Membre Héroïque
*
Hors ligne Hors ligne
Messages: 1258


Voir le profil
« #10 le: 13 Février 2008 à 19:17:34 »

Merci pour tous les conseils avisés que tu m'as donnés!

Pas de quoi. Je trouve que ça devient rare d'avoir un interlocuteur qui lit les réponses, les accepte et répond (qui plus est en français correct). D'autant que je m'attendais un peu à une réaction du genre «m'en tape de tes conneries, corrige moi mes bugs plutôt». Donc merci à toi aussi, tu me réconcilies un peu avec ce forum.

Citation
Quand _o_ m'a dit que ma fonction main était trop grande, et que je devais faire plusieurs fonction, je me suis dit: fait plusieurs .c, sinon le main.c regorgera de fonction et on devra tout le temps faire des aller-retour pour lire le code...

Je ne voulais pas aller trop vite en besogne, mais c'est effectivement une bonne idée. Cela dit, découper en fichier ne prend pas beaucoup de temps à partir du moment où le code est correctement structuré.

Citation
Tes conseils seront pris en compte! Et du point de vue logique, maintenant, le code marche! La seule chose que je n'ai pas trouvée, c'est l'histoire du RechercheLettre qui ne marche jamais du premier coup... Mais je cherche, je cherche!

Indice : regarde du côté de la valeur de la variable lettreEntree lors de l'appel à RechercheLettre.

Citation
Par contre, _o_, pourrais-tu me donner le nom de ton compo? Je n'arrive pas à mettre CodeBlocks en full warning...

Je confirme la réponse de Folcan : j'utilise gcc sous Linux. Il est disponible également sous Windows, du côté de MinGW ( http://www.mingw.org/ ). Pour ce qui est de Code::Blocks, il faut savoir qu'il ne s'agit que d'un IDE (de qualité d'après ce qu'on m'en a dit) qui peut utiliser plusieurs compilateurs différents, mais par défaut, il semblerait qu'il s'agisse justement du gcc MinGW. Si c'est le cas, tu ouvres la fenêtre suivante :

(http://www.codeblocks.org/docs/compiler_debugger.png)

Dans le cas de gcc, c'est le flag -Wall qui nous intéresse, donc il faut cocher «Enable all compiler warnings». Ah, et le -g peut aider également, il sert à avoir les symboles quand tu utilises un debugger (tiens, d'ailleurs, il n'y pas de debugger embarqué dans Code::Blocks ?).

Bon courage pour la suite.
« Dernière édition: 13 Février 2008 à 19:39:19 par _o_ » Journalisée

Les épreuves de hack de NC sont trop faciles ? Et pourtant ! Bienvenue dans la vraie vie : http://thedailywtf.com/Articles/So-You-Hacked-Our-Site!.aspx
Edurion

Profil challenge

Classement : 11366/54285

Néophyte
*
Hors ligne Hors ligne
Messages: 13


Voir le profil
« #11 le: 13 Février 2008 à 22:22:35 »

Citation
Pas de quoi. Je trouve que ça devient rare d'avoir un interlocuteur qui lit les réponses, les accepte et répond (qui plus est en français correct). D'autant que je m'attendais un peu à une réaction du genre «m'en tape de tes conneries, corrige moi mes bugs plutôt». Donc merci à toi aussi, tu me réconcilies un peu avec ce forum.

Je te retourne le "pas de quoi"! Quand on réponds à ta question, la moindre des choses est quand même de l'écouter et d'en prendre compte!

Pour Codes::Blocks, je me rappelai bien du -Wall, j'ai donc un peu farfouillé, et l'ai activé, mais il ne m'affichait rien de plus que d'habitude, c'est pour ça que j'ai demandé confirmation...

Merci pour l'indice! Ce n'était pas prévu, mais je vais m'y remettre tout de suite!

Enfin, merci, et bon courage à toi aussi !

Edurion

P.S.: Merci aussi à Folcan! J'aurais du faire un peu plus attention 
Journalisée
Edurion

Profil challenge

Classement : 11366/54285

Néophyte
*
Hors ligne Hors ligne
Messages: 13


Voir le profil
« #12 le: 15 Février 2008 à 16:18:46 »

Bonjour à tous!

Maintenant que le problème de lecture est résolu, alors que celui ne me faisait rien avant, je rencontre un problème avec le scanf du menu... J'étais au courant des différents inconvénients de scanf, c'est d'ailleurs pour ça que j'ai utilisé la fonction LireCaractere, et j'ai donc essayé avec d'autres fonction comme sscanf. J'ai même essayé scanf("%ld%*[^\n]"), mais rien n'y fait... Je cherche dons un moyen soit de remplacé scanf, soit de pouvoir vider le nombre en mémoire, et de recommencer la lecture du nombre entrée de manière propre. Pourriez-vous m'indiquez une piste?

Après avoir fait quelque test, ce n'est pas le scanf qui rencontre un problème, mais les appels aux fonctions... Je m'explique:

J'ai modifié mon code pour que le choix 3 lance une fonction ModeDAjout. Je lance donc mon programme.
1: Je choisi 1, le ModeUnJoueur (qui commence pas la fonction PiocherMot directement). Tout cela s'éxécute sans problème.
2: retour au menu: je refait 1, et la: "pendu.exe a rencontré une erreur et doit fermer..."

Je relance le programme:
1: ModeUnJoueur: sans problème
2: ModaDAjout; "pendu.exe a rencontré une erreur...."

Pareil si je fait deux fois ModeDAjout...

J'ai donc fait le test suivant:
1: MdeUnJoueur: pas de souci
2: l'option 2, le mode deux joueur, qui ne contient qu'un printf indiquant que le mode deux joueur n'est pas encore disponible, pas de problème...

C'est donc que lorsque j'appelle mes propres fonction, il y a un problème, même lorsque celles-ci n'ont pas étés utilisées la première fois... J'ai reegardé mes warnings, les ai tous résolus, rien à faire... Je ne comprends plus grand chose...Quelqu'un pourrait-il m'aider?


Au passage, quand j'ai essayé le scanf("%ld%*[^\n]"), suivi d'un getchar(), j'ai remarqué que le problème que je rencontrait avec la première lettre entrée qui ne marchait pas, était résolu?? O_o? Quelqu'un pourrait-il me dire pourquoi? je ne voit pas vraiment le rapport entre ce getchar() et le reste du code...

Merci d'avance!

Edurion
« Dernière édition: 16 Février 2008 à 12:06:56 par Edurion » Journalisée
_o_
Relecteur

Profil challenge

Classement : 42/54285

Membre Héroïque
*
Hors ligne Hors ligne
Messages: 1258


Voir le profil
« #13 le: 16 Février 2008 à 14:22:16 »

"pendu.exe a rencontré une erreur et doit fermer..."

Un bon gros crash, quoi. Le C est bas niveau et est très permissif. C'est ce qui en fait sa puissance, mais également sa grosse faiblesse : il est complexe de réussir à développer quelque chose de vraiment robuste. En bref, ce genre de symptômes, ça ressemble du jardinage en mémoire. L'utilisation d'un pointeur nul, l'accès à une zone mémoire non allouée, une double libération...

Pour résoudre ce problème, je ne peux que te re-proposer d'utiliser un débugger. Ça te permettrait de voir assez facilement à quel endroit ton programme crashe. Cela dit, c'est rarement à cet endroit là qu'on trouve le bug, mais c'est la condition impérative pour remonter la piste. Quant à donner un pointeur sur un débuggeur pour windows, joker (mais je suppose que gdb, le débugger gnu, est intégré à MinGW, et qu'il doit exister des frontends graphiques pour windows un peu moins rebutant que la ligne de commande de gdb).

Citation
J'ai reegardé mes warnings, les ai tous résolus, rien à faire... Je ne comprends plus grand chose...

Je précise : je t'ai dit de vérifier qu'il n'y avait pas de warnings à la compilation parce qu'ils sont en général révélateurs de bugs. Malheureusement, le compilateur ne voit pas tout, et il peut toujours y avoir des bugs sans warnings, ce serait trop facile...

Citation
Au passage, quand j'ai essayé le scanf("%ld%*[^\n]"), suivi d'un getchar(), j'ai remarqué que le problème que je rencontrait avec la première lettre entrée qui ne marchait pas, était résolu?? O_o? Quelqu'un pourrait-il me dire pourquoi? je ne voit pas vraiment le rapport entre ce getchar() et le reste du code...

Si tu as compris que toutes ses fonctions s'appliquaient à un flux contenant tout ce qui est tapé au clavier (dans le cas de l'entrée standard en général), tu devrais trouver assez facilement pourquoi tu as ce comportement. Ce qu'il faut bien se mettre en tête, c'est que ses fonctions ne se mettent pas en attente sur un évènement clavier, mais lisent un flux continu.

Pour ce qui est de développer proprement un programme interactif, je ne suis pas d'un grand secours. Je suis plutôt du genre à développer des batchs qui ne demandent pas grand chose d'autres que des paramètres de ligne de commande.

Citation
Quelqu'un pourrait-il m'aider?

Pour ton crash, poste le programme sur pastebin, et on verra ce qu'on peut faire. Sinon, tu peux passer sur le chan irc de nc, si je suis dispo, je te donnerais un coup de main.
Journalisée

Les épreuves de hack de NC sont trop faciles ? Et pourtant ! Bienvenue dans la vraie vie : http://thedailywtf.com/Articles/So-You-Hacked-Our-Site!.aspx
Edurion

Profil challenge

Classement : 11366/54285

Néophyte
*
Hors ligne Hors ligne
Messages: 13


Voir le profil
« #14 le: 16 Février 2008 à 14:44:58 »

Merci encore pour ces réponses!

Le C n'a décidément pas fini de nous embêter!

Je vais faire comme tu m'as dis, poster mon code sur pastebin. Je pense aussi en parler à quelqu'un de ma famille qui est ingénieur informatique, on verra bien!

Bon, je vais essayer de résoudre tout ça!

Merci aussi pour la curiosité du getchar(), qui n'en ai surement pas une, je vais me renseigner car je crois que j'ai zappé quelque chose...

Sûrement à bientôt et bonne continuation à tous!

Edurion
Journalisée
Pages: [1] 2
  Imprimer  
 
Aller à: