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 :

Mon petit programme est-il robuste ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut Mon petit programme est-il robuste ?
    Bonjour. J'ai créé un programme de style (trouvez le nombre) et je souhaite que vous le testiez dans le but de savoir s'il est si robuste qu'il en à l'air :

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include "myHeader.h"
    int main(void)
    {
      int hasard, argent;
      char code[2], saisie[2], choix[2];
     
      srand(time(NULL));
      hasard = rand() % (50+1);
     
      fprintf(stdout, "Samy Hocine - Programme\n");
      fprintf(stdout, "1 - Jouer\n");
      fprintf(stdout, "2 - Quitter\n\n");
      fprintf(stdout, "Votre choix:");
     
      fgets(choix, sizeof choix, stdin);
      fclean(choix, stdin);
     
      if(!strcmp(choix, "1")==0)
      {
                       return 0;
      }
      else
      {
     
      system(CLEAR);
     
      fprintf(stdout, "Entrez un nombre entre 10 et 20\n\nVotre nombre:");
      fgets(saisie, sizeof saisie, stdin);
      fclean(saisie, stdin);
      snprintf(code, sizeof code, "%i", hasard);
     
      if(strcmp (saisie, code)==0)
      {
                fprintf(stdout, "\n\nVous avez trouve le bon nombre\n\n");
      }
      else
      {
          fprintf(stdout, "\n\nVous n'avez pas trouve le bon nombre\n");
          fprintf(stdout, "Le bon nombre etait %i\n\n", hasard);
      }
     
      pause("Appuyez sur ENTRER pour continuer");
      system(CLEAR);
     
      return main();
     
      }
    }
    myHeader.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #ifndef MYHEADER_H
    #define MYHEADER_H
    #ifdef WIN32
       #define CLEAR "CLS"
    #elif defined (linux)
       #define CLEAR "clear"
    #else
       #error Not defined for this plateforme
    #endif
    void fclean(char *s_buffer, FILE *stream);
    void pause(char const *s_message);
    #endif //MYHEADER_H
    myHeader.cpp
    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
     
    #include <stdio.h>
    #include <string.h>
    #include <stddef.h>
    #include "myHeader.h"
    void fclean(char *s_buffer, FILE *stream)
    {
        if (s_buffer != NULL && stream != NULL)
        {
            char *pc = strchr(s_buffer, '\n');
     
            if (pc != NULL) /* La saisie n'a pas été tronquée */
            {
                 /* On remplace '\n' par le caractère nul '\0' */
                 *pc = 0;
            }
            else
            {
                /* La saisie a été tronquée, on purge le flux d'entrée */
                int c;
                while ((c = fgetc(stream)) != '\n' && c != EOF)
                {
                      //Rien
                }
            }
        }
    }
    void pause (const char *s_message)
    {
       if (s_message != NULL && strlen (s_message) != 0)
       {
          fprintf (stdout, "%s", s_message);
          fflush (stdout);
       }
       {
          char c[2];
          fgets (c, sizeof c, stdin);
          fclean (c, stdin);
       }
    }
    Merci d'avance

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Par défaut
    Quelques petites remarques en vitesse...

    myHeader.cpp je ne connais pas c'est l'extension d'un source C++. Renomme le myHeader.c


    Inclus <string.h> et <time.h> pour strcmp et time. Ce sera mieux.


    fprintf(stdout peut être remplacé par printf(.


    Les doubles négations ne facilitent pas la lecture. Préfère
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strcmp(choix, "1") != 0

    saisie n'est pas assez grand pour contenir un nombre entre 10 et 20.


    Revois le calcul de hasard. Tu ne tires pas un nombre entre 10 et 20. Difficile de gagner par conséquent. rand() tire entre 0 et RAND_MAX.

    Dans Numerical Recipes in C: The Art of Scientific Computing (William H. Press, Brian P. Flannery, Saul A. Teukolsky, William T. Vetterling; New York: Cambridge University Press, 1990 (1st ed, p. 207)), le commentaire suivant apparaît :

    "Si vous désirez engendrer un entier aléatoire entre 1 et 10, vous devez toujours procéder en utilisant les bits de poids forts, comme dans :

    j=1+(int) (10.0*rand()/(RAND_MAX+1.0));

    et jamais ainsi :

    j=1+(rand() % 10);

    (car cette derniere version utilise les bits de poids faibles)."

    C'est la première fois que je vois ça. Utilise une boucle while() à la place. En plus, ça te fait appeler srand() plusieurs fois. Il ne faut appeler srand qu'une seule fois.


    Tu ne contrôles pas que l'utilisateur rentre un nombre entre 10 et 20.

  3. #3
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    myHeader.cpp c'était une faute. En fait il se nomme bien myHeader.c (je code en c++ de temps en temps c'est pour ca)

    Si j'utilise "votre code" pour la génération de mots de passes, j'obtiens toujours la même chose pas avec "ma méthode".

    Je cherche à convertir un char en int (avez vous une idée ?) (dans le but de vérifier l'entrée)

    En fait, je m'étais trompé, c'est de 0 à 50

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #include "myHeader.h"
    int main(void)
    {
      int hasard;
      char code[2], saisie[2], choix[2];
     
      srand(time(NULL));
      hasard=rand()%(50+1);
      fprintf(stdout, "%i\n\n", hasard);
     
      fprintf(stdout, "Samy Hocine - Programme\n");
      fprintf(stdout, "1 - Jouer\n");
      fprintf(stdout, "2 - Quitter\n\n");
      fprintf(stdout, "Votre choix:");
     
      fgets(choix, sizeof choix, stdin);
      fclean(choix, stdin);
     
      if(strcmp(choix, "1")!=0)
      {
                       return 0;
      }
      else
      {
     
      system(CLEAR);
     
      fprintf(stdout, "Entrez un nombre entre 0 et 50\n\nVotre nombre:");
      fgets(saisie, sizeof saisie, stdin);
      fclean(saisie, stdin);
      snprintf(code, sizeof code, "%i", hasard);
     
      if(strcmp (saisie, code)==0)
      {
                fprintf(stdout, "\n\nVous avez trouve le bon nombre\n\n");
      }
      else
      {
          fprintf(stdout, "\n\nVous n'avez pas trouve le bon nombre\n");
          fprintf(stdout, "Le bon nombre etait %i\n\n", hasard);
      }
     
      pause("Appuyez sur ENTRER pour continuer");
      system(CLEAR);
     
      return main();
     
      }
    }
    Sinon, pour la boucle, je ne vois pas trop comment faire J'ai peur de voir apparaître indéfiniment mon programme dans la console

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Par défaut
    Si j'utilise "votre code" pour la génération de mots de passes, j'obtiens toujours la même chose pas avec "ma méthode".
    Oups je suis désolé. William H. Press, Brian P. Flannery, Saul A. Teukolsky et William T. Vetterling se sont trompés tous les quatre.
    Non, sérieusement ce code génére bien un nombre aléatoire. Ce n'est pas "mon code" ; c'est une "méthode" approuvée. Ton code de génération marche aussi mais a des défauts. Sinon, appelle srand () qu'une seule fois.

    Je cherche à convertir un char en int (avez vous une idée ?) (dans le but de vérifier l'entrée)
    Regarde atoi. Tu veux convertir un char * pas un char.

    Sinon, pour la boucle, je ne vois pas trop comment faire J'ai peur de voir apparaître indéfiniment mon programme dans la console
    Mais non mais non. Ta boucle doit tourner dans que l'utilisateur ne veux pas quitter. A toi de faire ce qu'il faut. Surtout qu'il n'y a pas grand chose à modifier... 3 lignes.

  5. #5
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par _SamSoft_ Voir le message
    Sinon, pour la boucle, je ne vois pas trop comment faire J'ai peur de voir apparaître indéfiniment mon programme dans la console
    Un problème à la fois. Pour le moment, ne fait pas de boucle (ou utilise l'astuce que je t'ai montré avec la saisie du nom du répertoire dans un autre projet).

    Déjà, je trouve que tu te disperses beaucoup. Mener 3 projets en même temps quand on débute, c'est pas très sérieux...

    Ensuite, tu dois te concentrer sur un sujet à la fois. Ici, tu cherches à manipuler des valeurs numériques. OK.

    Tu as réglé le problème de la saisie de chaine, c'est bien.

    Maintenant, il faut apprendre à saisir une valeur numérique. Pour ça, le principe est simple. On utlise fgets() et fclean() comme d'habitude, puis on convertit la chaine avec
    • strtol() si la valeur attendue est un entier signé (long)
    • strtoul() si la valeur attendue est un entier non signé (unsigned long)
    • strtod() si la valeur attendue est un réel (float)

    Avant de poser 3000 questions, lire la doc puis expérimenter... (ça n'a pas été fait déjà ?)

  6. #6
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Merci Je continuerai sûrement ca demain (après mes devoirs de maths ) ou mercredi prochain.

  7. #7
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Bonjour, j'ai plein de questions

    Déjà le code (j'ai juste ajouté ce qu'a dis Emmanuel) :

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #include "myHeader.h"
    int main(void)
    {
      int hasard;
      char code[2], saisie[2], choix[2], end;
     
      srand(time(NULL));
      hasard=rand()%(50+1);
      fprintf(stdout, "%i\n\n", hasard);
     
      fprintf(stdout, "Samy Hocine - Programme\n");
      fprintf(stdout, "1 - Jouer\n");
      fprintf(stdout, "2 - Quitter\n\n");
      fprintf(stdout, "Votre choix:");
     
      fgets(choix, sizeof choix, stdin);
      fclean(choix, stdin);
      end=(saisie[0]=='\0');
      if(!end)
      if(strcmp(choix, "1")!=0)
      {
                       return 0;
      }
      else
      {
     
      system(CLEAR);
     
      fprintf(stdout, "Entrez un nombre entre 0 et 50\n\nVotre nombre:");
      fgets(saisie, sizeof saisie, stdin);
      fclean(saisie, stdin);
      snprintf(code, sizeof code, "%i", hasard);
     
      if(strcmp (saisie, code)==0)
      {
                fprintf(stdout, "\n\nVous avez trouve le bon nombre\n\n");
      }
      else
      {
          fprintf(stdout, "\n\nVous n'avez pas trouve le bon nombre\n");
          fprintf(stdout, "Le bon nombre etait %i\n\n", hasard);
      }
     
      pause("Appuyez sur ENTRER pour continuer");
      system(CLEAR);
     
      return main();
      }
      while(!end);
      }
    Bon, j'ai essayé de découper mon programme en fonctions (pour supprimer cet affreux return main(); mais c'est une catastrophe, j'y arrive pas [une petite aide de ce côté serait la bienvenue).

    Je continu de dire que le code des 4programmeurs américains sur la génération de mots de passes ne donne que le même mot de passe à chaque fois (pas avec ma méthode ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    srand(time(NULL));
    hasard=(int) (50*rand()/(RAND_MAX+1));
    Emmanuel: Pourquoi dois-je utiliser strtol() alors que snprintf fait très bien son travail ?

    Pour les fprintf au lieu de printf, c'est parce que je préfère.

    Emmanuel: Je n'ai que deux projets "Listeur" et "Plus ou Moins". Deux tout petits en C c'est raisonnable maintenant si je voulais me lancer dans la création d'un os d'un côté et la création d'un langage de programmation de l'autre, là ce serait totalement idiot !

    Merci d'avance

Discussions similaires

  1. Je veux avoir de l'aide sur mon petit programme
    Par pdjelso dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 28/03/2014, 18h57
  2. [Lazarus] Qui veut tester mon petit programme de montage d'image
    Par jeanbi dans le forum Lazarus
    Réponses: 2
    Dernier message: 27/12/2009, 18h10
  3. aide sur mon petit programme
    Par ffsniper dans le forum Général Python
    Réponses: 4
    Dernier message: 30/06/2008, 15h24
  4. Est ce que mon programme est juste ?
    Par autoin dans le forum C
    Réponses: 6
    Dernier message: 25/01/2008, 17h06
  5. Mon programme est considéré comme un trojan -_-'
    Par peijnoob dans le forum Windows
    Réponses: 3
    Dernier message: 21/03/2007, 14h26

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