我正在使用一个名为的函数检查类型检查用户是否输入了有效的整数类型输入。例如,如果用户输入 15,它将打印valid15c 将打印无效。但是,如果用户仅输入字符串输入,例如ccccc,它会导致无限循环并且程序崩溃。我在下面添加了一些屏幕截图来显示输出。
int checkType(int input, char *c) {
if (input == 2 and *c == '\n') {
return 1;
} else {
return 0;
};
}
int main(void) {
int faces = 0;
char c;
int valid = 0;
int input;
while (valid == 0) {
printf("Enter number of faces: ");
input = scanf("%d%c", &faces, &c);
valid = checkType(input, &c);
printf(valid == 0 ? "not valid\n" : "valid\n");
}
}
![enter image description here](https://i.stack.imgur.com/8OXhp.png)
无限循环:
![enter image description here](https://i.stack.imgur.com/zTVfe.png)
The scanf()
函数族并不是真正为输入有问题的语法而设计的。
解决问题的常用方法是以一定会成功的方式读入所有输入,例如通过读取完整的行(而不是数字、类似单词的字符串或任何其他具有预期格式的内容)fgets()
。
然后您可以尝试按预期格式解析该行表示字符串。 (您可以使用sscanf()
如果失败,您可以忽略它并阅读下一行,或者尝试根据同一输入的替代允许格式进行解析。
相关的区别在于读取整行将成功并将其从输入流中删除。与此相反,如果语法失败,您的代码会在输入流中留下与预期语法不匹配的内容。因此,它当然会在读取循环的下一次迭代中再次失败。这就是导致你无限循环的原因。
详细地:
- 将整行读入缓冲区,
using fgets()
以及将字符数限制为缓冲区大小的选项
- 此时,所有行都从输入中删除(又名 stdin,又名输入流),
这意味着即使读取的行与任何允许的格式不匹配,下一次读取也将获得新的输入,
这是与尝试直接读取输入的相关区别scanf()
- 从行缓冲区中,尝试根据允许的格式读取单独的值,
using sscanf()
并检查返回值
- 如果成功的话,您已经填充了预期的变量(例如整数);
您可以尝试扫描其他非格式覆盖的尾随输入(并像不正确的输入一样继续,即使行的开头与允许的格式匹配)
- 如果不成功尝试不同的允许格式,
using sscanf()
again,
来自同一行缓冲区,即使格式部分匹配,该行缓冲区也不会更改
- 如果没有允许的格式与输入匹配,则需要考虑它不正确
- 不正确的输入可以被忽略或可能导致程序中出现致命的解析错误,您的选择
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)