43 votes

Vérifier si l'entrée est de type entier en C

Le problème est que je ne peux pas utiliser atoi ou une autre fonction de ce type (je suis presque sûr que nous sommes censés nous fier aux opérations mathématiques).

 int num; 
 scanf("%d",&num);
 if(/* num is not integer */) {
  printf("enter integer");
  return;
 }

J'ai essayé :

(num*2)/2 == num
num%1==0
if(scanf("%d",&num)!=1)

mais rien de tout cela n'a fonctionné.

Des idées ?

56voto

AndiDog Points 28417

num contiendra toujours un entier car c'est un int . Le site réel Le problème avec votre code est que vous ne vérifiez pas la scanf valeur de retour. scanf renvoie le nombre d'éléments lus avec succès, donc dans ce cas, il doit retourner 1 pour les valeurs valides. Si ce n'est pas le cas, une valeur entière non valide a été saisie et la fonction num n'a probablement pas été modifiée (c'est-à-dire qu'elle a toujours une valeur arbitraire parce que vous ne l'avez pas initialisée).

D'après votre commentaire, vous souhaitez uniquement permettre à l'utilisateur de saisir un nombre entier suivi de la touche Entrée. Malheureusement, cela ne peut pas être réalisé simplement par scanf("%d\n") mais il y a une astuce pour le faire :

int num;
char term;
if(scanf("%d%c", &num, &term) != 2 || term != '\n')
    printf("failure\n");
else
    printf("valid integer followed by enter key\n");

28voto

Paul R Points 104036

Vous devez d'abord lire votre entrée sous la forme d'une chaîne, puis analyser la chaîne pour voir si elle contient des caractères numériques valides. Si c'est le cas, vous pouvez la convertir en un nombre entier.

char s[MAX_LINE];

valid = FALSE;
fgets(s, sizeof(s), stdin);
len = strlen(s);
while (len > 0 && isspace(s[len - 1]))
    len--;     // strip trailing newline or other white space
if (len > 0)
{
    valid = TRUE;
    for (i = 0; i < len; ++i)
    {
        if (!isdigit(s[i]))
        {
            valid = FALSE;
            break;
        }
    }
}

21voto

John Bode Points 33046

Il y a plusieurs problèmes à utiliser scanf avec le %d pour ce faire :

  1. Si la chaîne d'entrée commence par un entier valide (tel que "12abc"), alors le "12" sera lu à partir du flux d'entrée et converti et assigné à num y scanf retournera 1, donc vous indiquerez un succès alors que vous ne devriez (probablement) pas ;

  2. Si la chaîne d'entrée n'a pas commencer par un chiffre, puis scanf ne liront pas tout les caractères du flux d'entrée, num ne sera pas modifié, et la valeur de retour sera 0 ;

  3. Vous ne précisez pas si vous devez gérer des formats non décimaux, mais cela ne fonctionnera pas si vous devez gérer des valeurs entières au format octal ou hexadécimal (0x1a). Le site %i gère les formats décimal, octal et hexadécimal, mais les deux premiers problèmes subsistent.

Tout d'abord, vous devrez lire l'entrée sous forme de chaîne de caractères (de préférence en utilisant la fonction fgets ). Si vous n'êtes pas autorisé à utiliser atoi vous n'êtes probablement pas autorisé à utiliser strtol soit. Vous devrez donc examiner chaque caractère de la chaîne. La manière la plus sûre de vérifier les valeurs numériques est d'utiliser la fonction isdigit (il existe également la fonction de bibliothèque isodigit y isxdigit pour vérifier les chiffres octaux et hexadécimaux, respectivement), tels que

while (*input && isdigit(*input))
   input++;    

(si vous n'êtes même pas autorisé à utiliser isdigit , isodigit o isxdigit puis giflez votre professeur pour avoir rendu le devoir plus difficile qu'il ne doit l'être).

Si vous devez être en mesure de gérer des formats octaux ou hexagonaux, les choses se compliquent un peu plus. La convention C veut que les formats octaux soient précédés d'un signe 0 et pour les formats hexadécimaux, un chiffre de tête 0x . Ainsi, si le premier caractère non blanc est un 0, vous devez vérifier le caractère suivant avant de savoir quel format non décimal utiliser.

Le schéma de base est le suivant

  1. Si le premier caractère non blanc n'est pas un '-', un '+', un '0' ou un chiffre décimal non nul, il ne s'agit pas d'une chaîne d'entiers valide ;
  2. Si le premier caractère non blanc est '-', il s'agit d'une valeur négative, sinon nous supposons une valeur positive ;
  3. Si le premier caractère est '+', il s'agit d'une valeur positive ;
  4. Si le premier caractère autre qu'un espace et un signe est un chiffre décimal non nul, alors l'entrée est au format décimal, et vous utiliserez la fonction isdigit pour vérifier les caractères restants ;
  5. Si le premier caractère autre qu'un espace et un signe est un '0', l'entrée est au format octal ou hexadécimal ;
  6. Si le premier caractère qui n'est ni un espace ni un signe est un '0' et que le caractère suivant est un chiffre compris entre '0' et '7', alors l'entrée est au format octal et vous utiliserez la fonction isodigit pour vérifier les caractères restants ;
  7. Si le premier caractère non blanc et non signe était un 0 et que le deuxième caractère est x o X Dans ce cas, l'entrée est au format hexadécimal et vous utiliserez la fonction isxdigit pour vérifier les caractères restants ;
  8. Si l'un des caractères restants ne satisfait pas à la fonction de vérification spécifiée ci-dessus, il ne s'agit pas d'une chaîne d'entiers valide.

4voto

abelenky Points 28063

Demandez-vous d'abord comment vous feriez jamais attendez de ce code qu'il PAS retourner un nombre entier :

int num; 
scanf("%d",&num);

Vous avez spécifié la variable comme étant de type entier, puis vous avez scanf mais sólo pour un nombre entier ( %d ).

Que pourrait-il contenir d'autre à ce stade ?

1voto

user16062049 Points 11

Si quelqu'un d'autre se pose cette question, j'ai écrit un programme, qui continue à demander d'entrer un nombre, si l'entrée de l'utilisateur n'est pas un nombre entier, et se termine quand un nombre entier est accepté.

#include<stdlib.h>
#include<stdio.h>
#include<stdbool.h>

bool digit_check(char key[])
{
    for(int i = 0; i < strlen(key); i++)
    {
        if(isdigit(key[i])==0)
        {
            return false;
        }
    }
    return true;
}

void main()
{
    char stroka[10];
    do{
        printf("Input a number: ");
        scanf("%s",stroka);}
    while (!digit_check(stroka));
    printf("Number is accepted, input finished!\n");
    system("pause");
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X