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

C语言程序出现Segmentation fault (core dumped),新手求问题排查

C语言问卷处理程序段错误(Segmentation fault)排查与修复

核心问题分析

你的问卷处理程序运行时触发段错误,主要由以下几个原因导致:

1. 受访者数量超出数组上限

responses数组定义为MAXR(100)行,但readresponses函数的循环未限制受访者数量上限。当输入的受访者超过100时,会访问responses[100][...]这类超出数组边界的内存,直接触发段错误。

2. 空响应导致数组越界

如果某条受访者记录的响应数量少于问题总数,未被赋值的responses[j][i]会保留全局初始值0。在calculatefrequencies中,反向计分后得到7-0=7,此时访问freq[7-1] = freq[6],但freq数组仅包含6个元素(索引0-5),越界访问触发段错误。

3. 字符串换行符干扰

fgets读取的行包含末尾换行符,strtok分割后,最后一个token会携带换行符(比如问题类型行的"Reverse"会变成"Reverse\n"),导致strcmp(token, "Reverse")匹配失败,错误将反向问题标记为正向,影响计分结果。


修复方案

  1. 限制受访者数量:在readresponses循环中添加*num_respondents < MAXR判断,避免数组越界。
  2. 初始化响应数组:处理每个受访者前,将其对应的响应行初始化为0,明确标记无效响应。
  3. 去除换行符:新增trim_newline函数,处理fgets读取的缓冲区和单个token,避免换行符干扰字符串比较。
  4. 过滤无效响应:在计算频率和得分时,跳过值为0的无效响应,避免越界和错误计分。

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXR 100
#define MAXQ 50

#define DIRECT 0
#define REVERSE 1

char questions[MAXQ][256];
int q_type[MAXQ];
int responses[MAXR][MAXQ];

// 去除字符串末尾的换行符
void trim_newline(char *str) {
    size_t len = strlen(str);
    if (len > 0 && str[len-1] == '\n') {
        str[len-1] = '\0';
    }
}

void readquestions(){
    char buffer[4096];

    // 读取问题
    if(fgets(buffer, sizeof(buffer), stdin) != NULL){
        trim_newline(buffer);
        char *token = strtok(buffer, ";");
        int i = 0;
        while (token != NULL && i < MAXQ){
            strncpy(questions[i], token, sizeof(questions[i])-1);
            questions[i][sizeof(questions[i])-1] = '\0'; // 确保字符串结束
            token = strtok(NULL, ";");
            i++;
        }
        // 初始化剩余问题为空
        for(; i < MAXQ; i++){
            questions[i][0] = '\0';
        }
    }

    // 读取问题类型
    if(fgets(buffer, sizeof(buffer), stdin) != NULL){
        trim_newline(buffer);
        char *token = strtok(buffer, ";");
        int i = 0;
        while(token != NULL && i < MAXQ){
            trim_newline(token); // 去除单个token的换行(如果有)
            if(strcmp(token, "Reverse") == 0){
                q_type[i] = REVERSE;
            }else{
                q_type[i] = DIRECT;
            }
            token = strtok(NULL, ";");
            i++;
        }
        // 初始化剩余类型为DIRECT
        for(; i < MAXQ; i++){
            q_type[i] = DIRECT;
        }
    }
}

void readresponses(int *num_respondents){
    char buffer[4096];
    *num_respondents = 0;

    while(fgets(buffer, sizeof(buffer), stdin) != NULL && *num_respondents < MAXR){
        if(buffer[0] == '#') continue;

        trim_newline(buffer);
        char *token = strtok(buffer, ",");

        // 跳过3个人口统计字段
        for(int i = 0; i < 3; i++){
            if(token == NULL) break;
            token = strtok(NULL, ",");
        }

        if(token == NULL){
            continue;
        }

        // 初始化当前受访者的响应为0(无效值)
        memset(responses[*num_respondents], 0, sizeof(responses[*num_respondents]));

        // 解析响应
        for(int i = 0; i < MAXQ; i++){
            if(token == NULL) break;

            trim_newline(token);
            if(strcmp(token, "fully disagree") == 0){
                responses[*num_respondents][i] = 1;
            }else if(strcmp(token, "disagree") == 0){
                responses[*num_respondents][i] = 2;
            }else if(strcmp(token, "partially disagree") == 0) {
                responses[*num_respondents][i] = 3;
            }else if(strcmp(token, "partially agree") == 0) {
                responses[*num_respondents][i] = 4;
            }else if(strcmp(token, "agree") == 0) {
                responses[*num_respondents][i] = 5;
            }else if(strcmp(token, "fully agree") == 0) {
                responses[*num_respondents][i] = 6;
            }
            token = strtok(NULL, ",");
        }
        (*num_respondents)++;
    }
}

void calculatefrequencies(int num_questions, int num_respondents){
    if(num_respondents == 0){
        printf("No respondents to calculate frequencies\n");
        return;
    }

    printf("FREQUENCIES ARE COMPUTED FOR EACH LEVEL OF AGREEMENT BELOW\n\n");

    for(int i = 0; i < num_questions; i++){
        int freq[6] = {0};

        for(int j = 0; j < num_respondents; j++){
            int response = responses[j][i];
            // 跳过无效响应(0)
            if(response < 1 || response > 6){
                continue;
            }
            if(q_type[i] == REVERSE){
                response = 7 - response;
            }
            // 确保response在1-6范围内,避免越界
            if(response >=1 && response <=6){
                freq[response - 1]++;
            }
        }

        printf("%s\n", questions[i]);
        for(int z = 0; z < 6; z++){
            double percent = (num_respondents > 0) ? (freq[z] * 100.0) / num_respondents : 0.0;
            printf("%.2f%%: %s\n", percent, 
                   (z == 0) ? "fully disagree" :
                   (z == 1) ? "disagree" :
                   (z == 2) ? "partially disagree" :
                   (z == 3) ? "partially agree" :
                   (z == 4) ? "agree" : "fully agree");
        }
        printf("\n");
    }
}

void calculatescores(int num_questions, int num_respondents){
    if(num_respondents == 0){
        return;
    }

    printf("SCORES FOR ALL RESPONDENTS\n");

    for (int r = 0; r < num_respondents; r++){
        int total_c = 0, total_i = 0, total_g = 0, total_u = 0, total_p = 0;

        for(int q = 0; q < num_questions; q++){
            int score = responses[r][q];
            if(score <1 || score >6){
                continue; // 跳过无效响应
            }
            if(q_type[q] == REVERSE){
                score = 7 - score;
            }

            if (q < 8) total_c += score;
            else if (q < 18) total_i += score;
            else if (q < 28) total_g += score;
            else if (q < 34) total_u += score;
            else total_p += score;
        }
        printf("C:%d, I:%d, G:%d, U:%d, P:%d\n", total_c, total_i, total_g, total_u, total_p);
    }
}

int main() {
    int num_questions = 0;
    int num_respondents = 0;

    readquestions();

    // 统计有效问题数量
    for(int i = 0; i < MAXQ; i++){
        if(questions[i][0] != '\0'){
            num_questions++;
        }else{
            break; // 遇到空问题就停止统计,假设问题是连续的
        }
    }

    readresponses(&num_respondents);
    calculatefrequencies(num_questions, num_respondents);
    calculatescores(num_questions, num_respondents);

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:37:32