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

Le hic est que je ne peux pas utiliser atoi ou toute autre fonction comme ça (je suis à peu près sûr que nous sommes censés compter sur des 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 aucun de ceux-ci n'a fonctionné.

Des idées?

24
demandé sur The Archetypal Paul 2010-11-01 22:04:13

13 réponses

num contiendra toujours un entier car c'est un int. Le problème réel avec votre code est que vous ne Vérifiez pas la valeur de retour scanf. scanf renvoie le nombre d'éléments lus avec succès, donc dans ce cas, il doit renvoyer 1 pour les valeurs valides. Si ce n'est pas le cas, une valeur entière invalide a été entrée et la variable 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).

A partir de votre commentaire, vous voulez seulement autoriser le utilisateur pour entrer un entier suivi de la touche Entrée. Malheureusement, cela ne peut pas être simplement réalisé par scanf("%d\n"), Mais voici 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");
32
répondu AndiDog 2010-11-01 20:03:47

Vous devez d'abord lire votre entrée sous forme de 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 le convertir en 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;
        }
    }
}
22
répondu Paul R 2018-01-23 17:16:28

Il y a plusieurs problèmes avec l'utilisation de scanf avec le spécificateur de conversion %d pour faire ceci:

  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, et scanf retournera 1, donc vous indiquerez le succès quand vous (probablement) ne devriez pas;

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

  3. Vous ne spécifiez 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 spécificateur de conversion %i gère les formats décimal, octal et hexadécimal, mais vous avez toujours les deux premiers problèmes.

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

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

(si vous n'êtes même pas autorisé à utiliser isdigit, isodigit, ou isxdigit, puis gifler votre professeur / professeur pour rendre la tâche plus difficile qu'elle ne l'est vraiment doit être).

Si vous devez être capable de gérer les formats octal ou hexadécimal, cela devient un peu plus compliqué. La convention C est pour les formats octaux d'avoir un premier chiffre 0 et pour les formats hexadécimaux d'avoir un premier 0x. Donc, si le premier caractère non-espace est un 0, Vous devez vérifier le caractère suivant avant de pouvoir savoir quel format non décimal utiliser.

Le contour de base est

  1. Si le premier caractère non-Espace n'est pas un '-', '+', '0', ou chiffre décimal non nul, alors ce n'est pas une chaîne entière valide;
  2. Si le premier caractère non-blanc est '-', alors c'est une valeur négative, sinon nous supposons une valeur positive;
  3. Si le premier caractère est"+", puis c'est une valeur positive;
  4. Si le premier caractère non-espace et non-signe est un chiffre décimal non nul, alors l'entrée est au format décimal, et vous utiliserez isdigit pour vérifier les caractères restants;
  5. Si le premier le caractère non-espace et non-signe est un '0', alors l'entrée est au format octal ou hexadécimal;
  6. Si le premier caractère non-espace et non-signe était un ' 0 'et le caractère suivant est un chiffre de' 0 ' à '7', alors l'entrée est au format octal, et vous utiliserez isodigit pour vérifier les caractères restants;
  7. Si le premier non-blanc et non du signe est 0, et le second caractère est x ou X, alors l'entrée est au format hexadécimal et vous allez utiliser 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 entière valide.
12
répondu John Bode 2010-11-01 20:19:18

Demandez-vous D'abord comment jamais s'attendre à ce que ce codene retourne pas un entier:

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

Vous avez spécifié la variable de type entier, alors vous scanf, mais seulement pour un entier (%d).

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

4
répondu abelenky 2010-11-01 19:38:14

J'ai regardé l'entrée de tout le monde ci-dessus, ce qui était très utile, et j'ai fait une fonction qui était appropriée pour ma propre application. La fonction évalue seulement que l'entrée de l'utilisateur n'est pas un "0", mais c'était assez bon pour mon but. Espérons que cette aide!

#include<stdio.h>

int iFunctErrorCheck(int iLowerBound, int iUpperBound){

int iUserInput=0;
while (iUserInput==0){
    scanf("%i", &iUserInput);
    if (iUserInput==0){
        printf("Please enter an integer (%i-%i).\n", iLowerBound, iUpperBound);
        getchar();
    }
    if ((iUserInput!=0) && (iUserInput<iLowerBound || iUserInput>iUpperBound)){
        printf("Please make a valid selection (%i-%i).\n", iLowerBound, iUpperBound);
        iUserInput=0;
    }
}
return iUserInput;
}
0
répondu Nick 2014-11-02 18:19:20

Essayez ceci...

#include <stdio.h>

int main (void)
{
    float a;
    int q;

    printf("\nInsert number\t");
    scanf("%f",&a);

    q=(int)a;
    ++q;

    if((q - a) != 1)
        printf("\nThe number is not an integer\n\n");
    else
        printf("\nThe number is an integer\n\n");

    return 0;
}
0
répondu OscaRoCa 2014-11-20 06:19:30

C'est un plus convivial je suppose:

#include<stdio.h>

/* This program checks if the entered input is an integer
 * or provides an option for the user to re-enter.
 */

int getint()
{
  int x;
  char c;
  printf("\nEnter an integer (say -1 or 26 or so ): ");
  while( scanf("%d",&x) != 1 )
  {
    c=getchar();

    printf("You have entered ");
    putchar(c);
    printf(" in the input which is not an integer");

    while ( getchar() != '\n' )
     ; //wasting the buffer till the next new line

    printf("\nEnter an integer (say -1 or 26 or so ): ");

  }

return x;
}


int main(void)
{
  int x;
  x=getint();

  printf("Main Function =>\n");
  printf("Integer : %d\n",x);

 return 0;
}
0
répondu sjsam 2016-03-03 06:39:40

J'ai développé cette logique en utilisant gets et loin des tracas scanf:

void readValidateInput() {

    char str[10] = { '\0' };

    readStdin: fgets(str, 10, stdin);
    //printf("fgets is returning %s\n", str);

    int numerical = 1;
    int i = 0;

    for (i = 0; i < 10; i++) {
        //printf("Digit at str[%d] is %c\n", i, str[i]);
        //printf("numerical = %d\n", numerical);
        if (isdigit(str[i]) == 0) {
            if (str[i] == '\n')break;
            numerical = 0;
            //printf("numerical changed= %d\n", numerical);
            break;
        }
    }
    if (!numerical) {
        printf("This is not a valid number of tasks, you need to enter at least 1 task\n");
        goto readStdin;
    }
    else if (str[i] == '\n') {
        str[i] = '\0';
        numOfTasks = atoi(str);
        //printf("Captured Number of tasks from stdin is %d\n", numOfTasks);
    }
}
0
répondu Shaimaa Yehia 2016-07-19 17:48:34
printf("type a number ");
int converted = scanf("%d", &a);
printf("\n");

if( converted == 0) 
{
    printf("enter integer");
    system("PAUSE \n");
    return 0;
}

Scanf () renvoie le nombre de spécificateurs de format qui correspondent, donc retournera zéro si le texte entré ne peut pas être interprété comme un entier décimal

0
répondu Eduardo 2017-03-04 16:28:12

J'avais le même problème, finalement compris quoi faire:

#include <stdio.h>
#include <conio.h>

int main ()
{
    int x;
    float check;
    reprocess:
    printf ("enter a integer number:");
    scanf ("%f", &check);
    x=check;
    if (x==check)
    printf("\nYour number is %d", x);
    else 
    {
         printf("\nThis is not an integer number, please insert an integer!\n\n");
         goto reprocess;
    }
    _getch();
    return 0;
}
-1
répondu vtolentino 2013-11-09 11:26:30

J'ai cherché une solution plus simple en utilisant uniquement des boucles et des instructions if, et c'est ce que j'ai trouvé. Le programme fonctionne également avec des entiers négatifs et rejette correctement toutes les entrées mixtes qui peuvent contenir à la fois des entiers et d'autres caractères.


#include <stdio.h>
#include <stdlib.h> // Used for atoi() function
#include <string.h> // Used for strlen() function

#define TRUE 1
#define FALSE 0

int main(void)
{
    char n[10]; // Limits characters to the equivalent of the 32 bits integers limit (10 digits)
    int intTest;
    printf("Give me an int: ");

    do
    {        
        scanf(" %s", n);

        intTest = TRUE; // Sets the default for the integer test variable to TRUE

        int i = 0, l = strlen(n);
        if (n[0] == '-') // Tests for the negative sign to correctly handle negative integer values
            i++;
        while (i < l)
        {            
            if (n[i] < '0' || n[i] > '9') // Tests the string characters for non-integer values
            {              
                intTest = FALSE; // Changes intTest variable from TRUE to FALSE and breaks the loop early
                break;
            }
            i++;
        }
        if (intTest == TRUE)
            printf("%i\n", atoi(n)); // Converts the string to an integer and prints the integer value
        else
            printf("Retry: "); // Prints "Retry:" if tested FALSE
    }
    while (intTest == FALSE); // Continues to ask the user to input a valid integer value
    return 0;
}
-1
répondu void 2014-10-04 01:34:30

Cette méthode fonctionne pour tout (entiers et même doubles) sauf zéro (elle l'appelle invalide):

La boucle while est juste pour l'entrée utilisateur répétitive. Fondamentalement, il vérifie si l'entier x / x = 1. Si c'est le cas (comme avec un nombre), c'est un entier/double. Si ce n'est pas le cas, ce n'est évidemment pas le cas.

#include <stdio.h> 
#include <math.h>

void main () {
    double x;
    int notDouble;
    int true = 1;
    while(true) {
        printf("Input an integer: \n");
        scanf("%lf", &x);
        if (x/x != 1) {
            notDouble = 1;
            fflush(stdin);
        }
        if (notDouble != 1) {
            printf("Input is valid\n");
        }
        else {
            printf("Input is invalid\n");
        }
        notDouble = 0;
    }
}
-1
répondu Danis Terzi 2016-01-27 11:18:53

J'ai trouvé un moyen de vérifier si l'entrée donnée est un entier ou non en utilisant la fonction atoi ().

Lisez l'entrée sous forme de chaîne et utilisez la fonction atoi() pour convertir la chaîne en entier.

La fonction Atoi () renvoie le nombre entier si la chaîne d'entrée contient un nombre entier, sinon elle retournera 0. Vous pouvez vérifier la valeur de retour de la fonction atoi() pour savoir si l'entrée donnée est un entier ou non.

Il y a beaucoup plus de fonctions pour convertir une chaîne en longue, double etc., Vérifiez la bibliothèque standard " stdlib.h" pour plus d'.

Remarque: cela ne fonctionne que pour les nombres non nuls.

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

int main() {
    char *string;
    int number;

    printf("Enter a number :");
    scanf("%s", string);

    number = atoi(string);

    if(number != 0)
        printf("The number is %d\n", number);
    else
        printf("Not a number !!!\n");
    return 0;
}
-2
répondu Rishi 2016-11-08 05:46:06