C语言中如何完善正整数输入的合法性校验?
解决正整数输入合法性校验问题
你的代码问题在于strtol遇到非数字字符时会停止转换,不会报错。比如输入53e,它会把前两位53转成整数,剩下的e被忽略,导致校验通过,但这其实是非法输入。下面给你两种靠谱的解决方法:
方法一:利用strtol的完整转换检查
strtol的第二个参数ptr会指向转换停止的位置,我们可以通过判断这个位置是否是字符串末尾('\0'),来确保整个输入都是数字字符。同时还要结合errno处理超出范围的情况:
#include <stdio.h> #include <stdlib.h> #include <errno.h> int main(int argc, char *argv[]) { if (argc < 2) { printf("请输入一个整数\n"); return 1; } char *ptr; errno = 0; // 重置errno long n = strtol(argv[1], &ptr, 10); // 检查三个条件: // 1. 转换后的数是正整数 // 2. 整个字符串都被转换(ptr指向末尾) // 3. 没有超出long范围,且不是无效转换 if (n <= 0 || *ptr != '\0' || (errno == ERANGE && (n == LONG_MIN || n == LONG_MAX))) { printf("the number should be a positive integer\n"); return 1; } printf("输入合法:%ld\n", n); return 0; }
解释:
*ptr != '\0':如果转换后还有剩余字符(比如53e里的e),说明输入包含非数字内容,直接判定非法。errno == ERANGE:处理输入超出long类型范围的情况(比如输入一个极大的数),这时候strtol会返回LONG_MIN或LONG_MAX并设置errno。
方法二:用isdigit遍历检查每个字符
如果你想用isdigit,可以遍历输入字符串的每个字符,确保全是数字,再转换为整数并检查是否为正:
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(int argc, char *argv[]) { if (argc < 2) { printf("请输入一个整数\n"); return 1; } char *input = argv[1]; // 检查空字符串 if (*input == '\0') { printf("the number should be a positive integer\n"); return 1; } // 遍历每个字符,确保都是数字 while (*input != '\0') { // 注意:isdigit的参数要转成unsigned char,避免char为有符号时的未定义行为 if (!isdigit((unsigned char)*input)) { printf("the number should be a positive integer\n"); return 1; } input++; } // 转换为整数并检查是否为正 long n = strtol(argv[1], NULL, 10); if (n <= 0 || errno == ERANGE) { printf("the number should be a positive integer\n"); return 1; } printf("输入合法:%ld\n", n); return 0; }
解释:
- 先遍历每个字符,用
isdigit检查是否为数字,只要有一个不是就报错。 - 最后还要检查转换后的数是否为正,以及是否超出范围(比如输入超长数字)。
两种方法对比
- 方法一更简洁,能同时处理范围检查和非法字符,推荐优先使用。
- 方法二更直观,适合对
strtol不太熟悉的场景,但需要额外遍历字符。
内容的提问来源于stack exchange,提问作者radoman
相关产品推荐
相关产品推荐

