C语言int输入验证:如何让用户重新输入非整数内容?
解决C语言中输入非整数时的重新输入问题
原代码的核心问题在于:使用scanf(" %d", &choice)读取整数时,若用户输入非数字内容,scanf会返回0(表示未成功读取整数),且错误输入会留在输入缓冲区中,导致后续输入操作直接读取垃圾数据;另外递归调用main()的做法存在栈溢出风险,不推荐使用。
以下是两种可行的解决方案:
方案一:利用scanf返回值+清空输入缓冲区
通过scanf的返回值判断是否成功读取整数,失败时清空输入缓冲区的残留内容,循环提示用户重新输入。
#include <stdio.h> #include <stdlib.h> // 假设login和user_signup已实现 void login() { printf("Login function called\n"); } void user_signup() { printf("Sign Up function called\n"); } int main() { int choice; int input_status; char temp; while (1) { printf("----------Welcome to Coffee Shop----------\n"); printf("\n\t1. Login \n"); printf("\t2. Sign Up \n"); printf("\nPlease enter 1 or 2: "); // 获取scanf的返回值,成功读取整数则返回1 input_status = scanf("%d", &choice); // 处理非数字输入 if (input_status != 1) { printf("Invalid input! Please enter a number (1 or 2).\n"); // 清空输入缓冲区,直到读取到换行符 while ((temp = getchar()) != '\n' && temp != EOF); continue; } // 处理数字不在有效范围内的情况 if (choice != 1 && choice != 2) { printf("Invalid Number! Please enter 1 or 2.\n"); continue; } // 输入有效,退出循环 break; } system("cls||clear"); switch (choice) { case 1: system("cls||clear"); login(); break; case 2: system("cls||clear"); user_signup(); break; } return 0; }
方案二:用fgets读取整行输入,再用sscanf解析
先读取整行输入到缓冲区,再从缓冲区中解析整数,彻底避免输入缓冲区残留问题。
#include <stdio.h> #include <stdlib.h> #include <string.h> void login() { printf("Login function called\n"); } void user_signup() { printf("Sign Up function called\n"); } int main() { int choice; char input_buf[100]; // 存储整行输入的缓冲区 while (1) { printf("----------Welcome to Coffee Shop----------\n"); printf("\n\t1. Login \n"); printf("\t2. Sign Up \n"); printf("\nPlease enter 1 or 2: "); // 读取整行输入,处理EOF异常 if (fgets(input_buf, sizeof(input_buf), stdin) == NULL) { printf("Input error!\n"); exit(1); } // 去除输入末尾的换行符 input_buf[strcspn(input_buf, "\n")] = '\0'; // 从缓冲区解析整数 if (sscanf(input_buf, "%d", &choice) != 1) { printf("Invalid input! Please enter a number (1 or 2).\n"); continue; } // 判断数字是否在有效范围内 if (choice != 1 && choice != 2) { printf("Invalid Number! Please enter 1 or 2.\n"); continue; } break; } system("cls||clear"); switch (choice) { case 1: system("cls||clear"); login(); break; case 2: system("cls||clear"); user_signup(); break; } return 0; }
为什么单独用isdigit()无效?
isdigit()仅用于判断单个字符是否为数字,无法直接处理整段输入。原代码中scanf读取失败时,错误输入会留在缓冲区,此时用isdigit()无法定位到正确的输入内容;且它无法判断输入是否为完整的有效整数(比如输入"12a",isdigit()会认为第一个字符是数字,但整体不是有效整数),因此单独使用无法解决问题。
内容的提问来源于stack exchange,提问作者Zhi Zheng
相关产品推荐
相关产品推荐

