c - 使用缓冲区而不是直接对整数使用 scanf 函数的原因
问题描述
所以我有这段代码,它是为读取用户输入而编写的,它应该在数字 1-9 之间。在代码中声明了 int “选择”。但不是使用scanf("%d", choice);
程序员直接扫描用户输入,而是使用 char 缓冲区并扫描缓冲区,然后使用 atoi 函数将 char 输入转换为整数。我很困惑为什么要这样做,而不是直接用简单的方法来做。我的假设是程序员已经这样做了,因此如果用户输入字符而不是数字,则代码不会出现故障。但如果是这种情况,那么 atoi 将如何将字母转换为整数?这是代码:
int readMenuChoice() {
while (1) {
char buffer[50];
size_t buffLen = 10;
int choice;
showMenu(); //another function that displays all options from 1 to 9
printf("Choose a menu option: ");
scanf("%[^\n]", buffer);
getchar();
choice = atoi(buffer);
if (choice > 0 && choice < 9) {
return choice;
}
printf("Invalid input\n\n");
}
}
解决方案
我们只能从编码器那里猜测意图。
但一个很可能的原因是确保每个输入之间的输入流为空。我个人也做类似的事情。但我会这样做:
while (1) {
char buffer[50];
int choice;
showMenu();
printf("Choose a menu option: ");
if(!fgets(buffer, sizeof buffer, stdin)) {
/* Handle error */
}
if(sscanf(buffer, "%d", &choice) != 1) {
/* Handle error */
}
if (choice > 0 && choice < 9) {
return choice;
}
printf("Invalid input\n\n");
}
atoi
是一个不安全的功能。如果参数无法解析为数字,则会调用未定义的行为。并且由于x = atoi(s)
完全等同于sscanf(s, "%d", &x)
,所以没有理由使用 unsafe 函数。sscanf
返回成功分配的数量,因此可以进行错误检查。
推荐阅读
- c++ - 在派生类中继承的重载增量运算符 ++
- java - 为什么 Head First 书在将请求从 Servlet 转发到 JSP 时使用“/”?
- javascript - 所有输入值的总和
- python - Python 中的 RabbitMQ 绑定交换
- reactjs - onClick时有什么方法可以根据className显示数据
- laravel - 在 dompdf 中使用分页符时如何解决设计中断
- ruby-on-rails - 开始调试 RoR 会话时如何自动运行 webpack-dev-server?
- ruby-on-rails - 从 Rails 4 升级到 Rails 6 并处理嵌套参数
- azure-devops - PAT 需要什么权限才能访问 https://analytics.dev.azure.com/ExtensionTestVee/TestProjectNOBR/_odata/v2.0//WorkItemSnapshot?API
- arrays - 在汇编中添加数组时找到数组的最小值