1

我编写了以下代码来从键盘获取整数。它将提示错误消息,直到您提供有效的整数值(负或正)。

一个条件是它必须检查每一个可能的测试用例

像:

-3.2 
5.0
984237.4329
0.343
.434
12344.
adfs34
233adds
3892710492374329
helloIamNotainteger 

对于所有这些测试,它都应该失败。它只会通过int >=INT_MIN && int <=INT_MAX 价值。

我的运行代码是:

#include<stdio.h>
#include<limits.h>

int min=INT_MIN;
int max=INT_MAX;

int main()
{
        char str[50],c; //I have taken size 50 please ignore this 
        int check;
 do
 {
        int flag=1,i=0,j=0,num=0;
        check=0;
        printf("Enter an Integer : ");
        while((c=getchar())!='\n')
                str[i++]=c;
        if(str[0] == '-')
        {
                flag = -1;
                j++;
        }
        for(;j<i;j++)
        {
                if(str[j] >= '0' && str[j] <= '9')
                        num=(str[j]-'0') + num*10;
                else
                        break;

        }
        if(j<i)
        {
          printf("Not an Integer, Please input an integer \n");
        }
        else if(num < min || num >max)
        {
          printf("Integer is out of range,Please input an integer \n");
        }
        else
        {
                num *=flag;
                printf("The given number is : %d\n",num);
                check=1;
        }
 }while(check == 0);
        return 0;

}

一个例子:对于这样的值。
83429439803248832409 (它是整数,但由于 range 应该失败)但它通过并给出了一些其他整数值。

如何在我的代码中解决这个问题或实现更好的想法getInt()

4

5 回答 5

2

最简单的方法是使用标准库函数。

#include <limits.h>
#include <stdlib.h>

int getInt (const char *s)
{
    long int n = strtol (s, NULL, 10);

    if (n < INT_MIN || n > INT_MAX)
        /* handle overflows */
    else
        return (int) n;
}

要处理其他错误,您可以使用几个条件。

#include <errno.h>

int getInt (const char *s, size_t size)
{
    const char *pEnd1 = s + size;
    char *pEnd2;
    long int n;

    errno = 0;

    n = strtol (s, &pEnd2, 10);

    if (n < INT_MIN || n > INT_MAX || errno != 0 || pEnd1 != pEnd2)
        /* error */
    else
        return (int) n;
} 
于 2012-11-08T11:54:09.373 回答
0

嘿,您正在尝试将大于 32768 的值存储到整数(非无符号)中。因此,当您这样做时,它将显示存储变量中存在的一些垃圾值。如您所知,c 中的整数有内存限制。像无符号类型的 int 数据类型可以存储 0 到 65535 之间的值。因此尝试存储更多的数字会导致问题。如果需要存储更大的数字,请尝试使用 long int 数据类型。也许它可能会有所帮助。但是该数据类型也有内存限制,其值接近 40 万或其他值。

希望有帮助。

于 2012-11-08T12:31:13.757 回答
0

虽然这更适合作为对Kirilenko良好检查解决方案的评论,但我的笔记会很长,所以我会将其发布为答案。

转换函数的主要问题是很难 ( strtol()) 甚至不可能 ( atoi()) 测试转换是否符合预期。

因此,当试图使事情变得更可靠(as atoi())和更容易使用(as )时,将使用Kirilenkostrtol()之类的解决方案。

无论如何,如果转换中出现问题(从调用者的角度来看),Omkant提供的方法仍然存在设计错误的问题。

所以接口应该更好地像许多其他系统函数一样,将它们的结果作为函数值返回:

/* 
 * Tryies to convert the first 'size' characters of 's' to an 'int' and optionally 
 * writes it to '*result'.
 * 
 * Returns the number of characters converted or any qualified negative error code
 * on failure.
 */
int getInt(
  const char * s,  /* source string to try to be converted to an integer */
  size_z size, /* number of digits to be converted (shall not be > strlen(s)) */
  int * result /* optional reference to an int to place the conversion result in */
);

并且,作为一个显着的副作用,NULL作为最后一个参数传递,一个能够简单地测试转换是否有效,此外,一个可以接收结果整数所需的位数。


然后仍然能够使用此转换函数,就好像它正在将其结果作为函数值返回一样,在某些情况下可能会很方便,可能需要使用以下宏:

GETINT(str, size, result, rc) \
  (rc = getInt(str, size, &result), result)

用法:

char s[] = "42";
int rc = 0;
int i = GETINT(s, 2, i, rc);
if (rc)
  /* some error */
else
  /* use i */
于 2012-11-08T13:36:12.450 回答
0

一种简单的方法是将它们作为字符串进行比较。首先,请注意 32 位整数不能超过 10 位(和一个符号)。

int32_t get_int32()
{
    char input[13];
    char check[12];
    int32_t result;

    if (scanf("%12s", input) != 1)
        /* handle error */
    /* ignore rest of number if any */
    ungetc('x', stdin);
    scanf("%*s");

    /* if length is bigger than 11, error */
    if (strlen(input) > 11)
        /* handle error */

    if (sscanf(input, "%"SCNd32, &result) != 1)
        /* handle error */
    sprintf(check, "%"PRId32, result);

    if (strcmp(input, check) != 0)
        /* handle error */

    return result;
}

请注意,strlen可以忽略该检查,并且strcmp会处理该检查。另请注意,如果您获得input足够check大(例如25),您可以安全地使用int,而不是int32_t因为您知道它不能超过 64 位(至少很多年)。

于 2012-11-08T13:44:22.473 回答
0

这是工作代码:请看这个,我没有这样做,strtol它满足所有条件并且只需要int

    #include<stdio.h>
    #include<limits.h>
    #include<string.h>

    int main()
    {
            int num;
            char str[500],c;
            int check;
            char max[12];
            char min[12];
            sprintf(max,"%d",INT_MAX);
            sprintf(min,"%d",INT_MIN);
     do
     {
            int flag=1,i=0,j=0;
            num=0;
            check=0;
            printf("Enter an Integer : ");
            while((c=getchar())!='\n')
                    str[i++]=c;
            str[i]='\0';
            if(str[0] == '-')
            {
                    flag = -1;
                    j++;
            }
            for(;j<i;j++)
            {
                    if(str[j] >= '0' && str[j] <= '9')
                            check = 1;               
                else
                {
                        check = 0;
                        break;
                }

        }
        if(check == 0)
        {
                printf("Not an Integer, Please input an integer \n");
        }
        /************Start of checking integer range **************/
        else
        {
                if( (flag == -1 && (strlen(str) > strlen(min))) || 
                    (flag == 1 && (strlen(str) > strlen(max))) )
                {
                        check = 0;
                        printf("Integer is out of range, \n");
                }
                else if(flag == -1 && (strlen(str) == strlen(min)) )
                {
                        i=0;
                        while(min[i]!='\0')
                        {
                                if (str[i] > min[i])
                                {
                                        check = 0;
                                        printf("Integer is out of range \n");
                                        break;
                                }
                                i++;                        }
                        if(check == 1)
                        {
                                for(j=1;j<strlen(str);j++)
                                        num=(str[j]-'0')+num*10;
                                num *=flag;
                                printf("The given number is : %d\n",num);
                        }
                }

                else if(flag == 1 && (strlen(str) == strlen(max)) )
                {
                        i=0;
                        while(max[i]!='\0')
                        {
                                if (str[i] > max[i])
                                {
                                        check = 0;
                                        printf("Integer is out of range\n");
                                        break;
                                }
                                i++;
                        }
                        if(check == 1)
                        {
                                for(j=0;j<strlen(str);j++)
                                        num=(str[j]-'0')+num*10;
                                num *=flag;
                                printf("The given number is : %d\n",num);
                        }
                }
                else
                {
                for(j=0;j<strlen(str);j++)
                        num=(str[j]-'0')+num*10;
                num *=flag;
                printf("The given number is : %d\n",num);
                }
        }
        /************End of checking integer range ****************/
 }while(check == 0);

return 0;
于 2012-11-08T19:26:22.417 回答