如何用scanf读取int或char?解决输入非数字时的无限循环问题
问题解决思路与修正代码
原代码的核心问题
- 类型不匹配:
choice是整数类型,choice == 'q'永远不会触发——'q'的ASCII值是113,只有输入113才会匹配,和需求完全不符。 - 缓冲区残留导致无限循环:用
scanf("%d")读取输入时,若用户输入非数字字符,scanf匹配失败,choice值不变,且输入缓冲区里的无效字符不会被清空,后续scanf会反复读取这些无效字符,陷入死循环。
修正方案:整行读取+输入校验
改用fgets读取整行输入,彻底清空缓冲区,再对输入内容做针对性校验,就能实现需求:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> int main() { int choice; char board[10] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}; // 模拟原代码中的board数组 char input[100]; // 足够容纳用户输入的缓冲区 do { printf("Enter a square, 1-9: "); // 读取整行输入,处理EOF等异常情况 if (fgets(input, sizeof(input), stdin) == NULL) { exit(1); } // 移除输入末尾的换行符 input[strcspn(input, "\n")] = '\0'; // 判断是否输入退出指令 if (strcmp(input, "q") == 0 || strcmp(input, "Q") == 0) { exit(0); } // 校验输入是否为纯数字 int is_valid_num = 1; for (int i = 0; input[i] != '\0'; i++) { if (!isdigit(input[i])) { is_valid_num = 0; break; } } if (!is_valid_num) { printf("请输入1-9的数字,或输入'q'退出\n"); continue; } // 将合法数字字符串转为整数 choice = atoi(input); // 校验数字范围 if (choice < 1 || choice > 9) { printf("数字必须在1-9之间\n"); } } while (choice < 1 || choice > 9); // 此处添加原代码中后续的逻辑处理 return 0; }
关键逻辑说明
- 整行读取:
fgets会一次性读取用户输入的所有内容(包括换行符),避免缓冲区残留无效字符,彻底解决无限循环问题。 - 退出判断:直接对比输入字符串是否为"q"/"Q",完全符合需求。
- 纯数字校验:遍历输入的每个字符,用
isdigit确保输入是纯数字,阻止非数字非q的无效输入。 - 范围校验:将合法数字转为整数后,判断是否在1-9区间内,不符合则提示重新输入。
内容的提问来源于stack exchange,提问作者Wes Smith
相关产品推荐
相关产品推荐

