C语言编写ncr函数不使用float变量检测浮点数输入并报错的方法
问题原因
你之前用scanf("%d")检测失效的核心原因是:%d格式符只会从输入流中读取连续的数字字符(可以带正负号),一旦遇到非数字字符就会停止读取,只要前面成功读取到了合法整数,就会返回1(匹配成功的数量),剩余的非数字字符会残留在输入缓冲区中。
你输入6.7时,第一个scanf("%d")成功读取了整数6,返回1,剩下的.7留在缓冲区,直到第二个scanf("%d")执行时遇到.无法匹配整数,才会触发错误,这就是你看到异常输出的原因。
解决方案
不需要引入float临时变量,只需要在每次读取整数后,校验输入流中剩余的字符是否为合法的空白分隔符(空格、换行、制表符等)即可:如果读取完整数后,输入流中还存在非空白的有效字符,就说明输入不是纯整数,判定为非法。
你可以封装一个通用的整数读取校验函数,示例实现如下:
#include <stdio.h> #include <ctype.h> // 用于isspace判断空白字符 // 读取整数并校验是否为纯整数输入 // 成功返回0,失败返回1 int read_valid_int(int *num, const char *prompt) { printf("%s", prompt); // 第一步:读取整数 if (scanf("%d", num) != 1) { // 清空缓冲区残留内容,避免影响后续输入 while (getchar() != '\n'); return 1; } // 第二步:校验剩余字符是否都是空白符 int c; // 跳过所有空白字符 while ((c = getchar()) != EOF && c != '\n' && isspace(c)); if (c != '\n' && c != EOF) { // 存在非空白的额外字符(比如小数点、字母等) // 清空剩余缓冲区 while (c != '\n' && c != EOF) c = getchar(); return 1; } return 0; } int ncr(int n, int r) { if (n - r < r) { r = n - r; } if (r == 0) { return 1; } else return ncr(n-1,r) + ncr(n-1,r-1); } int main() { int n, r; printf("Input :\n"); // 读取n并校验 if (read_valid_int(&n, "n = ")) { printf("Output : Invalid Input, n and r both should be integer numbers"); return 1; } // 读取r并校验 if (read_valid_int(&r, "r = ")) { printf("Output : Invalid Input, n and r both should be integer numbers"); return 1; } // 原有业务校验逻辑 printf("Output : "); if (n <= 0 || r < 0) { printf("Invalid input, n (or) r should be unsigned numbers"); } else if (n < r) { printf("Invalid input, n should be greater than or equal to r"); } else { printf("C(n, r) = %d", ncr(n,r)); } return 0; }
方案效果
- 输入
6.7时,读取n的阶段就会判定为非法,直接输出错误提示,不会走到读取r的步骤 - 输入
6、6(前后带空格)等合法整数输入可以正常通过校验 - 输入字母、特殊符号等非整数内容也会被直接拦截
内容的提问来源于stack exchange,提问作者Syam Manoj Kumar Paila
相关产品推荐
相关产品推荐

