当浮点值被赋值给int时,c中的语句进入无限循环



所以这是代码:

int num, counter = 1;
while (counter == 1)
{
printf_s("Enter a 5-digit integer :");
scanf_s("%d",&num);
if (num < 10000 || num > 99999)
{
puts("Please make sure the number you entered has 5 digits!n");
}
else if((num%100000 - num%10000)/10000 == num%10 && (num%100-num%10) == (num%10000-num%1000)/100 )
{
printf_s("%d is a 5-digit palindrome!n",num);
puts("Do you wish to continue? 1 = continue 0 = stop");
scanf_s("%d",&counter);
}
else
{
printf_s("%d is not a palindrome!n",num);
}
}

我没想到它会对float做任何有用的事情,因为我没有为它添加任何内容,但为什么它会进入一个无限循环,说"输入一个5位数的整数:(数字(不是回文"?

edit:原来我忘了添加变量num和counter的类型。并以某种方式调用while作为函数。

当浮点值被赋值给int时,c中的函数进入无限循环?

代码无法检查scanf_s("%d",&num);的返回值

int的非数字文本;123.456";则num取值123并且返回1。'.'未被消耗。CCD_ 6在随后的调用中重复失败;。456〃;。并且CCD_ 7不改变-无限循环。

相反,请检查输入函数的返回值。

// scanf_s("%d",&num);
if (scanf_s("%d",&num) != 1) {
puts("Fail");
break;
}

或者使用fgets()读取整行(通常(@一些程序员花花公子

我刚刚在scanf上运行了一个测试。

对于123.456,我认为会返回-1。但是它返回1,并且num将是123。它也对123x执行相同的操作。

然后,我意识到这可能是scanf需要的文件输入。

但是,考虑到检查有效用户输入(来自stdin(的上下文,我认为这很糟糕,我会使用strtol进行必要的检查。


以下是一些显示差异的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void
doscanf(const char *str)
{
int ret;
int num;
errno = 0;
ret = sscanf(str,"%d",&num);
printf("doscanf: str='%s' ret=%d num=%d -- %sn",
str,ret,num,strerror(errno));
}
void
dostrtol(const char *str)
{
errno = 0;
char *cp;
int num = strtol(str,&cp,10);
int valid = (*cp == 0);
printf("dostrtol: num=%d str='%s' cp='%s' valid=%d -- %sn",
num,str,cp,valid,strerror(errno));
}
int
main(void)
{
const char *strs[] = {
"123",
"456",
"",
"123.456",
"123x",
"x123",
NULL,
};
int sep = 0;
for (const char **str = strs;  *str != NULL;  ++str) {
if (sep)
printf("n");
sep = 1;
doscanf(*str);
dostrtol(*str);
}
return 0;
}

这是程序输出:

doscanf: str='123' ret=1 num=123 -- Success
dostrtol: num=123 str='123' cp='' valid=1 -- Success
doscanf: str='456' ret=1 num=456 -- Success
dostrtol: num=456 str='456' cp='' valid=1 -- Success
doscanf: str='' ret=-1 num=1 -- Success
dostrtol: num=0 str='' cp='' valid=1 -- Success
doscanf: str='123.456' ret=1 num=123 -- Success
dostrtol: num=123 str='123.456' cp='.456' valid=0 -- Success
doscanf: str='123x' ret=1 num=123 -- Success
dostrtol: num=123 str='123x' cp='x' valid=0 -- Success
doscanf: str='x123' ret=0 num=0 -- Success
dostrtol: num=0 str='x123' cp='x123' valid=0 -- Success

旁注:您的";是回文的";算法是硬接线,只取5位数字。

这没关系,但有点限制(而且不寻常(。下面是一个测试程序,展示了一个通用算法:

#include <stdio.h>
// orig -- OP original code (restricted/hardwired to 5 digit numbers)
int
orig(int num)
{
int palflg;
palflg = (num%100000 - num%10000)/10000 == num%10 &&
(num%100-num%10) == (num%10000-num%1000)/100;
return palflg;
}
// ispal -- generalized to any number
int
ispal(int num)
{
int digits[100];
int left = 0;
int right = 0;
int palflg = 1;
// split number into digits
for (;  num != 0;  num /= 10)
digits[right++] = num % 10;
// compare outer digits (working inward)
--right;
for (;  left <= right;  ++left, --right) {
palflg = (digits[left] == digits[right]);
if (! palflg)
break;
}
return palflg;
}
int
main(void)
{
int numbers[] = {
12345, 12312, 12321, 56465,
#ifndef RESTRICT
0, 1, 23, 123, 232, 1221, 12321, 123321,
#endif
};
for (int idx = 0;  idx < sizeof(numbers) / sizeof(numbers[0]);  ++idx) {
int num = numbers[idx];
int palflg = ispal(num);
int origflg = orig(num);
printf("%10d -- ispal=%s orig=%s -- %sn",
num,
palflg ? "is" : "not",
origflg ? "is" : "not",
(palflg == origflg) ? "PASS" : "FAIL");
}
return 0;
}

这是程序输出:

12345 -- ispal=not orig=not -- PASS
12312 -- ispal=not orig=not -- PASS
12321 -- ispal=is orig=is -- PASS
56465 -- ispal=is orig=is -- PASS
0 -- ispal=is orig=is -- PASS
1 -- ispal=is orig=not -- FAIL
23 -- ispal=not orig=not -- PASS
123 -- ispal=not orig=not -- PASS
232 -- ispal=is orig=not -- FAIL
1221 -- ispal=is orig=not -- FAIL
12321 -- ispal=is orig=is -- PASS
123321 -- ispal=is orig=not -- FAIL

最新更新