在 C 中检测 int 的逻辑

Posted

技术标签:

【中文标题】在 C 中检测 int 的逻辑【英文标题】:Logic in detecting int in C 【发布时间】:2014-02-16 05:05:26 【问题描述】:

我将不胜感激。我正在尝试创建这个简单的程序,它反复循环要求用户输入一个 int。如果他输入一个 int,它就会退出,但如果他输入其他东西或大于 int(例如 4gs4r33),它将再次循环要求输入一个 int。这是我尝试过的,但它不起作用。它说它是一个 int,即使它不是。

#include<stdio.h>

unsigned int findInt();

int main() 

printf("Please input an int.\n");
findInt();



unsigned int findInt() 
char input;
long num = 0;
int b = 0;

do 
    scanf("%c", &input);

    if (isdigit(input))
        num = num*10+input+'0';
        b = 1;
    
    else if (input == '\n')
        b = 1;
    else
        b = 0;
 while(input != '\n');    

if (b == 1)
    printf("Great!\n");
else
    printf("Not an int \n");
    findInt();
    
return 0;

【问题讨论】:

确实如此,因为每当你看到一个数字时你就设置 b = 1,并且输入以数字结尾。 【参考方案1】:

两种可能的方法。一种是修改您的代码:

b = 1;  // start off with good intentions…
do 
    scanf("%c", &input);

    if (isdigit(input))
        num = num*10+input -'0'; // *** SUBTRACT '0', don't add it!
    
    else if (input != '\n') 
        b = 0;
        break; // *** break when you find non-digit
    
 while (input != '\n');

两个变化:在计算整数时正确计算数学,并修复逻辑(这样当你找到非数字字符时,你就可以跳出循环)

第二种方法:

char buf[100];
char intAsString[100];
fgets(buf, 100, stdin);
sscanf(buf, "%d", num);
sprintf(intAsString, "%d\n", num);;
if(strcmp(buf, intAsString) == 0 ) 
  printf("yay - you entered an integer!\n");

我相信你可以弄清楚它是如何工作的。

更新一个完整的代码sn-p,它也解决了“循环逻辑”的问题:你从顶层调用一次findInt函数,它会一直运行,直到你得到诠释。注意 - 为了使其正常工作,我一次读取整个输入(而不是一次一个),然后使用 sscanf 一个一个地挑选字符(并手动更新指针)。它有很多优点——尤其是每次调用findInt 时都从一个新的输入开始,而不是让输入缓冲区的其余部分仍然需要读取(这会导致“不,不,不,太棒了!” - 因为您会一直阅读错误的输入,直到到达换行符,然后接受...)

#include<stdio.h>
#include <ctype.h>

unsigned int findInt();

int main() 
  findInt();


unsigned int findInt() 
char input;
char buf[100];
char *temp;
long num = 0;
int b = 0;
printf("please enter an int:\n");
fgets(buf, 100, stdin);
temp = buf;
do 
    sscanf(temp++, "%c", &input);
    if (isdigit(input))
        num = num*10+input-'0';
        b = 1;
    
    else if (input == '\n')
        
        b = 1;
        break;
        
    else 
        b = 0;
        break;
    
 while(input != '\n');

if (b == 1)
    printf("Great! %d is an integer!\n", num);
else
    printf("Not an int \n");
    findInt();
    
return 0;

【讨论】:

您好,非常感谢您的回复。当我现在运行它时,它会显示“Not an int”,然后是“Great”,然后退出。不再循环再次请求 int。会不会跟 while 语句后面的内容有关? 抱歉,我没有尝试修复您的循环逻辑。我怀疑 '\n' 仍在输入缓冲区中(也许您的系统会产生 \r\n ?)。在调用findIntfflush(stdin) 之间刷新输入缓冲区?现在在手机上很难正确检查... @pyramid - 抱歉回复延迟。我已经用我认为是解开谜团的方法(加上完整的工作代码)更新了我的答案。【参考方案2】:

else 分支中 - 即不是数字或换行符 - 你将 b 设置为 0。现在如果一个数字跟随你将其重置为 1。

您可能想要break 或以某种方式记录永久失败,而不是继续。

【讨论】:

感谢您的回复!我道歉,但我不明白。你能澄清一下吗? 您将b 设置为 1,然后设置为 0,然后再次设置为 1。在最后一个 else 在 b = 0 之后添加一个 break【参考方案3】:
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>

void findInt()
    int x;
    bool ok;

    do
        char buff[32], *endp;
        long long num;

        ok = true;//start true(OK)
        printf("Enter a number: ");
        fgets(buff, sizeof(buff), stdin);
        //strtoll : C99
        x=(int)(num=strtoll(buff, &endp, 0));//0: number literal of C. 10 : decimal number.
        if(*endp != '\n')
            if(*endp == '\0')
                printf("Too large!\n");//buffer over
                while('\n'!=getchar());
             else 
                printf("Character that can't be interpreted as a number has been entered.\n");
                printf("%s", buff);
                printf("%*s^\n", (int)(endp - buff), "");
            
            ok = false;
         else if(num > INT_MAX)
            printf("Too large!\n");
            ok = false;
         else if(num < INT_MIN)
            printf("Too small!\n");
            ok = false;
        
    while(!ok);

,

【讨论】:

以上是关于在 C 中检测 int 的逻辑的主要内容,如果未能解决你的问题,请参考以下文章

检测到 glibc - 在 C 程序中释放(int ** 类型)时出现双重释放或损坏消息

c ++检测用户是不是输入字符串而不是Int [关闭]

C++ 从 istream 读取 int,检测溢出

Objective C中iOS的图像模糊检测

调用函数后检测到 C 堆栈粉碎

C语言:数组长度的检测方法