Как проверить числовое значение на языке Си? - PullRequest
3 голосов
/ 13 октября 2011

Этот вопрос задавался ранее, но я так и не нашел ясного и простого ответа, поэтому я спрашиваю его снова ...

Я хотел бы знать, не используя другие библиотекичем stdio.h, как проверить, является ли введенное пользователем числовое значение или нет.Обычно пользователю предлагается ввести значение от 0 до 9. Если число находится между этими двумя, оно продолжается.Например, если число равно 12, оно возвращается к вопросу и снова запрашивает число.

Оно работает нормально, за исключением того, что если я ввожу букву ИЛИ десятичное число, оно входит в бесконечный цикл...

По сути, это мой вопрос: как я могу проверить, что введенное значение не является символом и не является десятичным?

Вот начало кода: (извините, это по-французски, но вы поняли ...)

int main()
{

int nb1, nb2, rand_1, rand_2;
int nb_coups = 0;
int points = 0;

printf("\n\n                     ------ BIENVENUE A LA GRANDE ROUE ! ------\n\n");

do{
    //Saisie 1er nombre

    printf("Entrez le premier nombre choisi (entre 0 et 9) : ");
    scanf("%d",&nb1);

    //Tant que le 1er nombre n'est pas compri entre 0 et 9, on le redemande
        while(nb1<0 || nb1>9)
        {
            printf("Nombre incorrect. Entrez le premier nombre choisi (entre 0 et 9) : ");
            scanf("%d",&nb1);
        }
    //On affiche le 1er nombre
    printf("Le nombre choisi est : %d\n\n",nb1);

Ответы [ 5 ]

3 голосов
/ 13 октября 2011

Не используйте scanf () для ввода с консоли.Вместо этого используйте fgets () для чтения данных из stdin в строку, а затем проанализируйте их, или используйте getchar () для чтения символа за раз.Если в вашей среде есть такая штука, вы также можете рассмотреть getch (), который, когда поддерживается, обычно читает напечатанный символ, не ожидая возврата после него.

2 голосов
/ 13 октября 2011

С fgets и sscanf:

char line [16];

fprintf(stderr, "Entrez le premier nombre choisi (entre 0 et 9) : ");
fgets (line, sizeof(line), stdin);
ret = sscanf(line,"%d",&nb1);

//Tant que le 1er nombre n'est pas compri entre 0 et 9, on le redemande
while((ret == 0) || (nb1 < 0) || (nb1 > 9)) {
    fprintf(stderr, "Nombre incorrect. Entrez le premier nombre choisi (entre 0 et 9) : ");
    fgets (line, sizeof(line), stdin);
    ret = sscanf(line,"%d",&nb1);
}
1 голос
/ 13 октября 2011

Вы должны проверить возвращаемое значение, чтобы отсеять не числа.

printf("Entrez le premier nombre choisi (entre 0 et 9) : ");
ret = scanf("%d",&nb1);

//Tant que le 1er nombre n'est pas compri entre 0 et 9, on le redemande
    while(!ret && (nb1<0 || nb1>9))
    {
        char ch;
        while ((ch = getchar()) != '\n' && ch != EOF); // Flush the buffer
        printf("Nombre incorrect. Entrez le premier nombre choisi (entre 0 et 9) : ");
        ret = scanf("%d",&nb1);
    }
0 голосов
/ 03 ноября 2011

Мне нравится общее назначение:

Общее назначение, с некоторой защитой от переполнения и допускает некоторую универсальность, если вам нравится другой диапазон.

#include <ctype.h>
int atoi(char   *s, int N)
{
   int  n;  /* value being accumulated          */
   int  sign;   /* =1 if result is positive, -1 if negative */

   while((N>0)&&(*s == '\t' || *s == ' '))
   {
      N--;
      s++;  /* skip white space             */
   }
   sign=1;      /* assume a positive value          */

   if(*s == '+' || *s == '-')
   {
      N--;
      sign = *s++ == '-' ? -1 : 1;  /* adjust result sign   */
   }
   for(n=0; (N>0)&&isdigit(*s); s++,N--)
      n = n * 10 + *s - '0';

   return (sign * n);   /* result adjusted for sign     */
}
0 голосов
/ 13 октября 2011

Не используйте scanf, выполните синтаксический анализ самостоятельно.

char c;
int nb1 = 0;
while(1) {
    c = getchar();
    if(c > '0' && c < '9') {
        nb1 = nb1*10 + (c - '0'); // if you want numbers bigger than 9
    }
    else {
        break; // matches '\n', invalid chars and EOF
    }
}

Voila!

...