我编写了以下代码来从键盘获取整数。 它将提示错误消息,直到您给出有效的整数值(负数或正数)。
一个条件是它必须检查每个可能的测试用例
像:
-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(它是整数但由于范围会失败)但它会传递并给出一些其他整数值。
如何在我的代码中解决此问题或更好地实现getInt()
?
答案 0 :(得分: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;
}
答案 1 :(得分:0)
嘿,你试图将一个大于32768的值存储到整数(非unsigned)中。因此,当您这样做时,它将显示存储变量中存在的一些垃圾值。如你所知,c中的整数有内存限制。像无符号类型的int数据类型可以存储0到65535之间的值。因此,尝试存储多于一个的数字将导致问题。如果需要存储更大的数字,请尝试使用long int数据类型。也许它可能有所帮助。但是该数据类型也具有内存限制,其值接近4lakh或其他值。
希望有所帮助。
答案 2 :(得分:0)
虽然这最适合作为对 Kirilenko 检查解决方案的评论,但我的说明会很长,所以我会将其作为答案发布。
会聚函数的主要问题是难以(strtol()
)不可能(atoi()
)来测试转换是否达到了预期的效果。
因此,当尝试使事情更可靠(如atoi()
)并且更易于使用(如strtol()
)时,将使用 Kirilenko 等解决方案。
无论如何, 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
作为最后一个参数,能够简单地测试转换是否有效,并且另外一个人可以接收结果整数所需的位数。 / p>
然后仍然可以使用这个转换函数,就像它将结果作为函数值返回一样,在某些情况下可能会很方便,可能会使用以下宏:
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 */
答案 3 :(得分: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位(至少多年)。
答案 4 :(得分: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;