IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

problème inexplicable [Débutant(e)]


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2011
    Messages : 5
    Par défaut problème inexplicable
    Bonjour à tous !

    Je viens de me mettre au C grâce au merveilleux tutorial de Mateo. Je voulais savoir si quelqu'un pouvais m'expliquer pourquoi ce code ne marche pas (j'ai tenté de réaliser le TP "plus ou moins" du tutorial) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 1000
    #define MIN 1
     
    int eval(long x, long y);
     
    int main()
    {
        int b = 1; // parametre de boucle general (pour recommencer des parties)
        while (b)
        {
            srand(time(NULL));
            long numAleat = (rand()%(MAX-MIN+1))+MIN; // nombre aleatoire
     
            long varEntree = 0; // nombre donne par le joueur
     
            int a = 1; // simple parametre de boucle (a l'interieur d'une partie)
     
            while (a)
            {
     
                printf("Tapez un nombre :\n");
                scanf("%ld",&varEntree);
     
     
                switch (eval(numAleat, varEntree))
                {
                case 0 :
                    printf("PLUS!\n");
                    break;
                case 1 :
                    printf("MOINS!\n");
                    break;
                case 2 :
                    printf("BRAVO!\nRejouer ? o = oui n = non\n");
                    char ka = 'o';
                    long* point = NULL;
                    point = &ka;
                    scanf("%s",point);
                    printf("%c",*point);
                    if ((*point) == 'o')
                    {
                        printf("ok");
                        b = 1;
                    }
                    else
                    {
                        printf("aie");
                        b = 0;
                    }
                    a = 0;
                    break;
                }
            }
        }
     
     
     
     
        return 0;
    }
     
     
    /* fonction servant à evaluer le nombre donne
    par le joueur par rapport au nombre aleatoire */
    int eval(long x, long y)
    {
        if (x > y )
        {
            return 0;
        }
        else if (x<y)
        {
            return 1;
        }
        else
        {
            return 2;
        }
    }
    tout marche impec, sauf quand je demande à ce que le joueur tape o pour refaire une partie (d'où la grosse boucle while qui a pour paramètre b) ou n pour quitter.
    là j'ai beau faire je tape o en exécution et il me dit toujours que ka != 'o'...
    j'ai essayé de mettre un pointeur, mais faut croire que ça marche pas à tous les coups...
    je suis perdu ^^

    merci d'avance !

    Bonne journée

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 485
    Par défaut
    Bonjour et bienvenue !

    Oui, effectivement, tu t'emmêles un peu les pinceaux avec ton pointeur dans le « case 2 » :


    Citation Envoyé par martin1418 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
                case 2 :
                    printf("BRAVO!\nRejouer ? o = oui n = non\n");
                    char ka = 'o';
                    long* point = NULL;
                    point = &ka;
                    scanf("%s",point);
                    printf("%c",*point);
                    if ((*point) == 'o')
                    {
                        printf("ok");
                        b = 1;
                    }
                    else
                    {
                        printf("aie");
                        b = 0;
                    }
    • est un caractère, qui contient la lettre « o » par défaut. Il occupe donc un seul octet en mémoire, sur la plupart des machines conventionnelles ;
    • est un pointeur sur un entier long, donc rien à voir avec un caractère. Un tel entier tient généralement sur 4 octets, et non 1 ;
    • : ici, tu charges le pointeur avec l'adresse de ton caractère. À ce stade, le compilateur doit déjà se plaindre en te disant que ce ne sont pas les mêmes. Cependant, c'est techniquement faisable, donc il te laisse faire. Le problème est que lorsque tu vas déréférencer le pointeur pour aller lire ce qu'il pointe, ton programme va essayer de récupérer un long. Il va donc lire le caractère et les trois octets qui le suivent, dont la valeur est indéfinie. Tu obtiendras donc un résultat erroné, et peut être une segfault puisque tu dépasses la zone officiellement lisible ;
    • sert à charger une chaîne de caractère et pas un caractère seul. Ça veut dire que cet appel va aller écraser en mémoire tout ce qui se trouve après ton caractère ka, et provoquer des bugs. Il est même problable que cela aille modifier la valeur des flags « a » et « b », puisqu'ils se trouvent juste après tes variables, dans la pile. Ceci risque de provoquer des comportements inexplicables. Il aurait au moins fallu utiliser plutôt que « %s ». Mieux : il aurait fallu utiliser fgetc() à la place ;
    • : en écrivant ceci, tu vérifies si le long est égal au code ASCII de « o », mais ce long dépend également, comme dit plus haut, des trois octets indéfinis qui suivent ka. Le résultat sera toujours différent de « o », sauf si ces trois octets sont nuls.


    Abandonne le pointeur, et utilise fgetc() à la place pour charger ka directement. Attention : cette fonction renvoie un int et pas un char, parce qu'elle peut éventuellement te renvoyer EOF si elle ne peut plus lire l'entrée standard ou le fichier qui en tient lieu. Il faudra gérer ce cas de figure.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2011
    Messages : 5
    Par défaut
    aussi je voulais dire que si j'ai utilié %s au lieu de %c c'est parce que quand je mettais le dernier, le programme se terminait sans même me demander de taper quelque chose... quelqu'un saurait pourquoi ?

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2011
    Messages : 5
    Par défaut
    merci pour ces conseils !

    juste, j'ai modifié le code et voilà ce que m'a dit codeblocks lors du débuggage :

    "tk - Debug" uses an invalid compiler. Probably the toolchain path within the compiler options is not setup correctly?! Skipping...
    Nothing to be done.

    que dois-je faire ?

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char ka = 'o';
    long* point = NULL;
    point = &ka;
    scanf("%s",point);
    scanf("%s",point) lit une chaine de caractères en sautant les <Blanc> (caractères pour lesquels isspace() est vrai) qui précèdent et en s'arrêtant au premier <Blanc> rencontré et ajoute un '\0' terminal à la fin. En conséquence, point doit être un tableau d'au moins deux caractères. Avec deux caractères, on doit se contenter de ne taper qu'un caractère avant le retour chariot, sinon plantage.
    Pour éviter ceci, on peut spécifier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char ka[2];
    scanf("%1s",ka);
    printf("%c",*ka);
    if (*ka == 'o')....
    qui sautera les blancs en tête et ne lira qu'un caractère sur le clavier (et laissera les suivants dans le buffer, ce qui peut poser problème ensuite)

    Comme alternative, on ne peut lire qu'un caractère avec %c comme format. En général, on est gêneé avec ce format car souvent il traine dans le buffer clavier des caractères venant d'une entrée précédente (comme un '\n'). Pour sauter ces caractères <Blanc> qui traine dans le buffer, faire précéder %c par un blanc.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char ka ; 
    scanf(" %c",&ka);
    printf("%c",ka);
    if (ka == 'o').....

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2011
    Messages : 5
    Par défaut
    merci !

    et pour mon problème de codeblocks ? il m'affiche toujours lors de la compilation :

    "tk - Debug" uses an invalid compiler. Probably the toolchain path within the compiler options is not setup correctly?! Skipping...
    Nothing to be done.

    je peux plus rien faire ! help !

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 485
    Par défaut
    Citation Envoyé par martin1418 Voir le message
    "tk - Debug" uses an invalid compiler. Probably the toolchain path within the compiler options is not setup correctly?! Skipping...
    Nothing to be done.
    Je n'utilise pas Code::Blocks mais, à vue de nez, c'est ton IDE qui cherche à appeler le débogueur et qui ne le trouve pas. Il te dit alors d'aller voir dans les options si le chemin d'accès vers l'exécutable est toujours valable.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2011
    Messages : 5
    Par défaut
    j'ai réinstallé codeblocks, tout baigne !

    merci à tous pour tout

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 20/03/2015, 18h15
  2. [Débutant] Problème inexplicable avec méthode récursive
    Par sylvebarbe78 dans le forum C#
    Réponses: 2
    Dernier message: 06/02/2014, 17h43
  3. Problème inexplicable avec une TreeMap (containsKey)
    Par fabrisss dans le forum Langage
    Réponses: 4
    Dernier message: 10/06/2011, 10h18
  4. Problème d'installation oracle 8.1.7 sous NT
    Par Anonymous dans le forum Installation
    Réponses: 7
    Dernier message: 02/08/2002, 14h18
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo