检查输入是不是是C中的整数类型

Posted

技术标签:

【中文标题】检查输入是不是是C中的整数类型【英文标题】:Check if input is integer type in C检查输入是否是C中的整数类型 【发布时间】:2011-05-03 14:22:57 【问题描述】:

问题是我不能使用 atoi 或任何其他类似的函数(我很确定我们应该依赖数学运算)。

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

我试过了:

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

但这些都不起作用。

有什么想法吗?

【问题讨论】:

“这些都不起作用”是什么意思?最后一个是怎么试的? @David 我把它们放在 if 语句中,有什么令人困惑的地方? “整数类型”是什么样的输入?一个只由数字组成的?前面可以加减号吗? 您列出了两个条件和一个 if 语句。我假设您没有在 if 语句中包含 if 语句,所以我不知道您在那里做了什么。 (您只是替换了 if 语句,还是比这更重要?)除了“这些都不起作用”之外,您也没有提供任何故障模式的线索。没有编译?运行时错误?没有按您预期的方式工作(如果是,您的预期是什么?)? 我知道我迟到了,但我想你“不能”(意思是:不允许)使用atoi(),因为这个想法是你通过步行“手动”进行检查通过字符并检查它们是否在 0-9 范围内。因此很可能scanf() 也不应该被使用。 【参考方案1】:

num 将始终包含一个整数,因为它是一个int。您的代码真正的问题是您没有检查scanf 返回值。 scanf 返回成功读取的项目数,因此在这种情况下,它必须返回 1 作为有效值。如果不是,则输入了一个无效的整数值,并且num 变量可能没有被更改(即仍然具有任意值,因为您没有对其进行初始化)。

在您的评论中,您只想允许用户输入一个整数,然后输入回车键。不幸的是,这不能简单地通过scanf("%d\n") 实现,但这里有一个技巧:

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");

【讨论】:

不,我检查了返回值,即使对于像“2k”这样的非整数,它也是“1”。 @sombe:当scanf 正在读取一个数字并检测到一个非数字字符时,它会简单地停在那里并将其留给流(在这种情况下,只需“返回”2) @eq 没关系,如果用户插入非整数键,我必须检测它并打印错误。 @sombe:已编辑以允许您的用例。 我试过了,它确实有效,我真的希望它没问题。非常感谢。【参考方案2】:

您需要先将输入读取为字符串,然后解析字符串以查看它是否包含有效的数字字符。如果是,那么您可以将其转换为整数。

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;
        
    

【讨论】:

有没有办法用正则表达式实现这一点? @sombe:当然,使用正则表达式验证整数只是\d+。但是 C 有正则表达式吗? 请不要建议使用危险的gets() @sombe 您确实需要这样做,但在检查它是否有效后,您需要添加一个 sscanf(s, "%d", num); ,它将从中生成一个整数。 @sombe,您能告诉我们实际要求吗?我的猜测是你也应该处理字符串->十进制转换(这就是我写作业的方式)【参考方案3】:

使用带有%d 转换说明符的scanf 来执行此操作存在几个问题:

    如果输入字符串以有效整数开头(如“12abc”),则从输入流中读取“12”并转换并赋值给numscanf将返回1,所以当你(可能)不应该表示成功时,你会表示成功;

    如果输入字符串以数字开头,那么scanf将不会从输入流中读取任何个字符,num会不改变,返回值为0;

    您没有指定是否需要处理非十进制格式,但如果您必须处理八进制或十六进制格式 (0x1a) 的整数值,这将不起作用。 %i 转换说明符处理十进制、八进制和十六进制格式,但您仍然遇到前两个问题。

首先,您需要将输入读取为字符串(最好使用fgets)。如果不允许您使用atoi,您可能也不允许使用strtol。因此,您需要检查字符串中的每个字符。检查数字值的安全方法是使用 isdigit 库函数(还有 isodigitisxdigit 函数分别用于检查八进制和十六进制数字),例如

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

(如果你甚至不被允许使用isdigitisodigitisxdigit,那么就责备你的老师/教授让作业变得比实际需要的更难)。

如果您需要能够处理八进制或十六进制格式,那么它会变得更复杂一些。 C 约定是八进制格式有一个前导 0 数字,十六进制格式有一个前导 0x。因此,如果第一个非空白字符是 0,则必须先检查下一个字符,然后才能知道要使用哪种非十进制格式。

基本大纲是

    如果第一个非空白字符不是“-”、“+”、“0”或非零十进制数字,则这不是有效的整数字符串; 如果第一个非空白字符是'-',那么这是一个负值,否则我们假设一个正值; 如果第一个字符是“+”,那么这是一个正值; 如果第一个非空白和非符号字符是非零十进制数字,则输入为十进制格式,您将使用isdigit检查剩余字符; 如果第一个非空白和非符号字符是“0”,则输入为八进制或十六进制格式; 如果第一个非空白和非符号字符是“0”,下一个字符是从“0”到“7”的数字,则输入为八进制格式,您将使用isodigit检查剩余的字符; 如果第一个非空白和非符号字符是0,第二个字符是xX,则输入为十六进制格式,您将使用isxdigit检查剩余字符; 如果任何剩余的字符不满足上面指定的检查函数,那么这不是一个有效的整数字符串。

【讨论】:

【参考方案4】:

首先问问自己,你会如何曾经期望这段代码返回一个整数:

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

您将变量指定为整数类型,然后是 scanf,但为整数 (%d)。

此时它还可能包含什么?

【讨论】:

抱歉,人们似乎对这个答案赞不绝口,但我完全预料到你从算法中写的内容,但它没有用。我应该检查该值,使其永远不是非整数,并且您的解决方案不会削减它。我错过了什么吗?请解释一下。 @sombe:您缺少的是scanf("%d",&amp;num) 只会将整数值存储到num 根据定义该值是否与输入字符串有任何关系是一个悬而未决的问题。如果您输入带有前导数字的内容(如“12efg”),scanf 将读取、转换并分配前导“12”,将“efg”留在输入流中。如果输入字符串不是以数字开头(例如“ab123”),则将读取输入字符串的none,并且num 将包含它在调用之前的任何值(其中仍然是一个整数)。 “此时它还可能包含什么?” --> 一个陷阱值 - 虽然我已经多年没有看到 int 使用陷阱了。【参考方案5】:

如果有人提出这个问题,我写了一个程序,如果用户的输入不是整数,它会一直要求输入一个数字,并在接受一个整数时结束

#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");

【讨论】:

【参考方案6】:

我看了上面大家的输入,很有用,做了一个适合我自己应用的函数。该函数实际上只是评估用户的输入不是“0”,但对于我的目的来说已经足够了。希望这会有所帮助!

#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;

【讨论】:

代码在使用iUserInput之前应该检查scanf("%i", &amp;iUserInput)的返回值。【参考方案7】:

试试这个...

#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;

【讨论】:

scanf("%f",&amp;a);a 的无效数字输入未初始化,q=(int)a; 未定义。代码应该在使用a之前检查scanf("%f",&amp;a)的返回值。【参考方案8】:

我猜这是一个更人性化的:

#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;

【讨论】:

while( scanf("%d",&amp;x) != 1 ) 循环是无限循环,如果stdin 关闭,scanf("%d",&amp;x) 将永远返回EOF。还有while ( getchar() != '\n' )【参考方案9】:

我使用gets和远离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);
    

【讨论】:

str[10] 不足以容纳较大的 int 值。【参考方案10】:
printf("type a number ");
int converted = scanf("%d", &a);
printf("\n");

if( converted == 0) 

    printf("enter integer");
    system("PAUSE \n");
    return 0;

scanf() 返回匹配的格式说明符的数量,因此如果输入的文本不能解释为十进制整数,则返回零

【讨论】:

【参考方案11】:

我一直在寻找一个只使用循环和 if 语句的更简单的解决方案,这就是我想出的。该程序还可以处理负整数,并正确拒绝任何可能同时包含整数和其他字符的混合输入。


#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;

【讨论】:

scanf("%d"... 将接受 "+123" "-1234567890",此答案也无法正确处理。【参考方案12】:

只需检查您的号码是否与浮动版本有任何区别。

float num; 
scanf("%f",&num);

if(num != (int)num) 
    printf("it's not an integer");
    return;

【讨论】:

【参考方案13】:

此方法适用于除零之外的所有内容(整数甚至双精度数)(称为无效):

while 循环仅用于重复的用户输入。基本上它检查整数 x/x = 1。如果是(就像使用数字一样),它是一个整数/双精度数。如果不是,那显然不是。零没有通过测试。

#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;
    

【讨论】:

scanf("%lf", &amp;x);x 的无效数字输入未初始化,x/x 未定义。【参考方案14】:

我遇到了同样的问题,终于想通了:

#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;

【讨论】:

conio.h 不保证分布在所有平台上。 scanf ("%f", &amp;check); 会将"987654321" 之类的输入四舍五入到最接近的float 值,而不使用printf("\nYour number is %d", x); 打印原始值【参考方案15】:

我找到了一种使用 atoi() 函数检查给定输入是否为整数的方法。

将输入读取为字符串,并使用 atoi() 函数将字符串转换为整数。

atoi()函数如果输入的字符串包含整数则返回整数,否则返回0。可以查看atoi()函数的返回值来判断给定的输入是否为整数。

还有很多函数可以将字符串转换成long、double等,更多请查看标准库“stdlib.h”。

注意:它仅适用于非零数字。

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

int main() 
    char *string;
    int number;

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

    number = atoi(string);

    if(number != 0)
        printf("The number is %d\n", number);
    else
        printf("Not a number !!!\n");
    return 0;

【讨论】:

没有分配给string的内存,所以scanf("%s", string);是UB。

以上是关于检查输入是不是是C中的整数类型的主要内容,如果未能解决你的问题,请参考以下文章

c语言中如何检查输入值是不是为数字

C 试图检查无效输入

c语言中如何实现输入一个整数实现倒序输出

检查输入到文本字段的值是不是是给定范围内的整数

日期只输入一个整数而不是C中的日月年

如何检查输入数字整数是不是不浮动?