You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言入门:未完全理解指针,输入add命令触发段错误求助

C语言add命令段错误问题排查与修复

核心错误点梳理

  • 野指针访问(最直接的段错误诱因)
    main函数中char* cmdLine仅定义了字符指针,没有分配任何可写入的内存空间,直接调用gets(cmdLine)会向随机内存地址写入数据,直接触发段错误。同时gets函数本身是已被废弃的不安全函数,完全不限制写入长度,极易造成内存溢出。
  • 空指针访问
    1. 当add命令没有带参数时,代码没有跳过handleAdd(input)的调用,会直接把NULL传入处理函数,后续访问该指针直接崩溃。
    2. handleAdd中写了循环把addCommand遍历到NULL后,又调用strlen(addCommand)对空指针求长度,直接触发段错误。
  • strtok用法错误
    1. main函数中input = strtok(NULL, "");用空字符串作为分隔符,会把add后面的所有内容当成一整串,无法拆分出各个数字参数,正确分隔符应为空格" "。
    2. strtok依赖全局状态保存拆分进度,main中拆分过命令行后,在handleAdd中直接调用strtok(NULL, " ")无法正确接续拆分参数,需要对传入的参数字符串重新初始化拆分。
  • 逻辑错误
    1. 直接读取参数字符的ASCII值存入坐标数组,没有转成整数,就算不崩溃存储的数值也完全错误。
    2. 用字符值的奇偶判断是x坐标还是y坐标,逻辑完全错误,应该按参数的位置判断:第1、3、5……个参数为x坐标,第2、4、6……个为y坐标。

入门级修复方案

第一步:修复main函数的输入逻辑

int main() {
    printf("Create a polygon using the add command. Valid commands are add, summary, turn, shift, and quit.\n");
    while (1) {
        // 分配固定长度的数组存储输入,不要用野指针
        char cmdLine[256];
        char* command;
        char* input;
        printf(">>");
        // 用安全的fgets替代gets,限制最大输入长度
        fgets(cmdLine, sizeof(cmdLine), stdin);
        // 去掉fgets读取到的末尾换行符
        cmdLine[strcspn(cmdLine, "\n")] = '\0';
        
        command = strtok(cmdLine, " ");
        // 处理空输入的情况
        if (command == NULL) continue;
        
        if (strcmp(command, "quit") == 0)
             break;
        else if (!strcmp(command, "add")) {
            // 分隔符用空格,拆分第一个参数
            input = strtok(NULL, " ");
            if (input == NULL) {
                printf("Too few aguments for add command! It must be in the form of add x1 y1 x2 y2 xn yn.\n");
                // 没有参数就不要调用处理函数
                continue;
            }
            handleAdd(input);
        }
    }
    return 0;
}

第二步:修复handleAdd函数逻辑

// 假设你已经提前定义了全局的坐标数组和计数变量,示例定义如下:
// int xCoords[100], yCoords[100];
// int pointCount = 0;
void handleAdd(char* addCommand) {
    // 先复制参数到本地数组,避免strtok修改原字符串
    char paramBuf[256];
    strcpy(paramBuf, addCommand);
    // 初始化拆分,分隔符为空格
    char* token = strtok(paramBuf, " ");
    int paramIndex = 0;
    // 循环拆分所有参数
    while (token != NULL) {
        // 把字符串转成整数
        int num = atoi(token);
        // 参数下标从0开始,偶数位是x,奇数位是y
        if (paramIndex % 2 == 0) {
            xCoords[pointCount] = num;
        } else {
            yCoords[pointCount] = num;
            // 每存完一对x y,点数计数加1
            pointCount++;
            // 简单防止数组越界,示例中设置最多存100个点
            if (pointCount >= 100) break;
        }
        paramIndex++;
        // 拆分下一个参数
        token = strtok(NULL, " ");
    }
}

内容的提问来源于stack exchange,提问作者Jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 00:36:03