| 12
 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
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 
 |  
#include <stdio.h>
#include <stdlib.h>
 
/* -ed- ajoutes... */
#include <string.h>
#include <errno.h>
#include <limits.h>
 
/* -ed-
int Nombre(void);
 
   Il est rarement utile de definir un prototype
   separe quand la fonction est privee (non exportee)
 
   Il suffit generalement de respecter le principe
   'definir avant d'utiliser'
 
   Le mot cle 'static' affirme le caractere non exportable de la fonction.
 
   Ajout d'un parametre 'err'
*/
static int Nombre(int *p_err)
{
/* -ed- valeur retournee par defaut... */
   int n = 0;
 
/* -ed-
   char chnClavier[5]=" ";
 
   Il n'est pas utile d'initialiser la chaine
   (et puis pourquoi un espace ?)
 
   La taille est ridiculement petite.
   Un int peut faire au minimum de -32767..32767
   soit un minimum de 6+1+1 = 8 char.
 
   Je mets de 16 a 32 pour etre tranquille. Disons 16.
*/
   char chnClavier[16];
 
/* -ed-
   fgets(chnClavier,5,stdin);
 
   l'operateur sizeof facilite la maintenance...
*/
   fgets (chnClavier, sizeof chnClavier, stdin);
 
/* -ed-
   verifier que l'on a pas deborde...
   Si c'est le cas, vider stdin.
*/
   {
      /* search ... */
      char *p = strchr (chnClavier, '\n');
 
      if (p != NULL)
      {
         /* ... and kill */
         *p = 0;
      }
      else
      {
          /* flush stdin the proper way */
          int c;
          while ((c = getchar()) != '\n' && c != EOF)
          {
          }
      }
   }
 
/* -ed-
   return strtol(chnClavier,NULL,10);
   Pa si vite. il se peut que la conversion ait echouee.
   Il faut le verifier.
*/
 
   {
      int err = 1;
 
      /* -ed- as-t-on saisi quelque chose ? */
      if (*chnClavier != 0)
      {
         char *p_end;
         long ln = strtol (chnClavier, &p_end, 10);
 
         /* -ed- la conversion a-t-elle reussie ? */
         if (p_end != NULL && *p_end == 0)
         {
            /* y'a-t-il eu debordement ? */
            if (errno != ERANGE)
            {
               /* Les limites sont-elles acceptables ? */
               if (ln >= INT_MIN && ln <= INT_MAX)
               {
                  n = (int) ln;
                  err = 0;
               }
            }
         }
      }
 
      /* -ed- mettre a jour l'etat err chez l'appelant. */
      if (p_err != NULL)
      {
         *p_err = err;
      }
   }
   return n;
}
 
int main (void)
{
   int c, d, err;
 
/* -ed-
   printf("Entrez 2 nombres :");
 
   La chaine n'etant pas une ligne (manque '\n'),
   ajout d'un .
 
   fflush (stdout);
 
   Presentation deplorable. Amelioration...
*/
 
   printf("Entrez 2 nombres :\n");
 
   printf ("Nombre 1 : ");
   fflush (stdout);
   c = Nombre (&err);
 
   /* -ed- ce traitement de l'erreur est un choix parmi d'autres. */
   if (!err)
   {
      printf ("Nombre 2 : ");
      fflush (stdout);
      d = Nombre(&err);
 
      if (!err)
      {
         printf("%d et %d\n", c, d);
      }
      else
      {
         puts("saisie nombre 2 erronee");
      }
   }
   else
   {
      puts("saisie nombre 1 erronee");
   }
 
/* -ed-
   system("pause");
 
   particularisme du a l'utilisation de Dev-C++...
 */
 
   return 0;
} | 
Partager