C程序传参触发Segmentation fault问题排查求助
问题分析与解决
核心错误原因
段错误的直接原因是**isdigit(argv[i])的调用完全错误**:
isdigit函数的参数要求是单个字符(准确说是unsigned char类型的值,需强制转换避免负数字符的未定义行为),而argv[i]是指向字符串的指针(char*类型)。你直接把指针传入isdigit,函数会把这个指针的地址值当作字符的ASCII码去处理,相当于尝试访问一个非法的内存地址,必然触发段错误。
修正方案
要实现“检查参数是否为纯数字(支持负号可额外处理)”,需要遍历每个参数字符串的每一个字符,逐一检查是否为数字(或负号,若允许负数):
- 对每个
argv[i],先判断是否为空字符串(避免空参数的异常) - 若字符串以
'-'开头,从第二个字符开始检查是否全为数字;否则从第一个字符开始检查 - 遍历过程中只要发现非数字字符,立即输出
Error并退出
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <ctype.h> int main(int argc, char *argv[]) { int i, j; int sum = 0; if (argc == 1) { printf("0\n"); return 0; } for (i = 1; i < argc; i++) { // 处理空参数的情况 if (argv[i][0] == '\0') { printf("Error\n"); return 1; } // 检查第一个字符是否是负号或数字 j = 0; if (argv[i][j] == '-') { j++; // 如果只有负号,没有后续数字,也算非法 if (argv[i][j] == '\0') { printf("Error\n"); return 1; } } // 遍历剩余字符,检查是否全为数字 for (; argv[i][j] != '\0'; j++) { // 强制转成unsigned char,避免负数字符的未定义行为 if (!isdigit((unsigned char)argv[i][j])) { printf("Error\n"); return 1; } } sum += atoi(argv[i]); } printf("%d\n", sum); return 0; }
额外说明
- 原代码的循环条件
i < argc是没问题的,确实能保证访问argv的合法范围 - 如果你的需求不允许负数,直接去掉负号的判断逻辑即可,从第一个字符开始检查是否全为数字
内容的提问来源于stack exchange,提问作者fromesoli
相关产品推荐
相关产品推荐

