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

Geany中执行糖尿病数据计算C代码无输出问题求助

代码无输出的问题排查与修复

核心问题分析

你的代码运行无输出,主要由以下关键错误导致:

  • 未初始化变量:getData函数中的i和j未初始化,初始值为随机垃圾值,导致逻辑分支混乱,程序提前进入错误流程。
  • 指针误用与内存越界:nationalAverage是单个double类型指针,你却用nationalAverage[(int)atof(token)-2015]当作数组访问,直接触发内存访问错误,导致程序崩溃。
  • 统计数组未初始化:provincialAverages、yearlyAverages、ageGroupAverages等数组在main中未初始化,初始值为垃圾值,统计结果完全错误。
  • CSV解析逻辑错误:处理年龄组时重复调用strtok,导致数据读取错位;年份和数值的累加逻辑缺失计数,无法正确计算平均值。
  • 全国平均值逻辑缺失:未对全国数据做累加和求平均的处理,直接输出初始垃圾值。

修复后的完整代码

// Include libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Function prototypes
void getData(FILE* fp, double* provincialAverages, double* nationalSum, int* nationalCount, 
             double* yearlyAverages, int yearlyCounts[4][7], 
             double* ageGroupAverages, int ageGroupCounts[5][3]);
void calculateAverages(double* provincialAverages, double nationalAverage, 
                       double* yearlyAverages, int yearlyCounts[4][7], 
                       double* ageGroupAverages, int ageGroupCounts[5][3]);

int main(){
    FILE *fp;
    // 初始化所有统计变量为0,避免垃圾值干扰
    double provincialAverages[4] = {0.0};
    double nationalSum = 0.0;
    int nationalCount = 0;
    double yearlyAverages[4][7] = {0.0}; // 4个省份 × 7年(2015-2021)
    int yearlyCounts[4][7] = {0};        // 年份数据计数
    double ageGroupAverages[5][3] = {0.0};// 5个区域(4省+全国) × 3个年龄组
    int ageGroupCounts[5][3] = {0};      // 年龄组数据计数
    
    // 打开文件
    fp = fopen("statscan_diabetes.csv", "r");
    if (fp == NULL){
        printf("Error opening file.\n");
        return 1;
    }
    
    getData(fp, provincialAverages, &nationalSum, &nationalCount, 
            (double*)yearlyAverages, yearlyCounts, 
            (double*)ageGroupAverages, ageGroupCounts);
    calculateAverages(provincialAverages, nationalSum / nationalCount, 
                      (double*)yearlyAverages, yearlyCounts, 
                      (double*)ageGroupAverages, ageGroupCounts);

    fclose(fp);
    return 0;
}

// 读取CSV数据并统计累加值
void getData(FILE *fp, double *provincialAverages, double *nationalSum, int *nationalCount, 
             double *yearlyAverages, int yearlyCounts[4][7], 
             double *ageGroupAverages, int ageGroupCounts[5][3]){
    char line[200];
    char *token;
    double sum[4] = {0.0};
    int count[4] = {0};
    int i, j;
    
    // 跳过CSV表头行
    fgets(line, sizeof(line), fp);
    
    while (fgets(line, sizeof(line), fp) != NULL){
        token = strtok(line, ",");
        i = 0;
        j = -1; // 初始化区域索引为无效值
        double value = 0.0;
        int yearIdx = -1;
        int ageIdx = -1;
        
        while (token != NULL){
            // 跳过前4个无关字段
            if (i < 4){
                token = strtok(NULL, ",");
                i++;
            }
            // 识别区域/省份
            else if (i == 4){
                if (strcmp(token, "Ontario") == 0) j = 0;
                else if (strcmp(token, "Quebec") == 0) j = 1;
                else if (strcmp(token, "British Columbia") == 0) j = 2;
                else if (strcmp(token, "Alberta") == 0) j = 3;
                else if (strcmp(token, "Canada excluding territories") == 0) j = 4;
                token = strtok(NULL, ",");
                i++;
            }
            // 识别年份
            else if (i == 5){
                int year = atoi(token);
                if (year >= 2015 && year <= 2021) yearIdx = year - 2015;
                token = strtok(NULL, ",");
                i++;
            }
            // 识别年龄组
            else if (i == 6){
                if (strcmp(token, "35 to 49 years") == 0) ageIdx = 0;
                else if (strcmp(token, "50 to 64 years") == 0) ageIdx = 1;
                else if (strcmp(token, "65 years and over") == 0) ageIdx = 2;
                token = strtok(NULL, ",");
                i++;
            }
            // 获取数值
            else if (i == 7){
                value = atof(token);
                token = strtok(NULL, ",");
                i++;
            }
        }
        
        // 仅处理有效数据
        if (j != -1 && value > 0 && yearIdx != -1 && ageIdx != -1){
            // 省份数据统计
            if (j < 4){
                sum[j] += value;
                count[j]++;
                yearlyAverages[j*7 + yearIdx] += value;
                yearlyCounts[j][yearIdx]++;
                ageGroupAverages[j*3 + ageIdx] += value;
                ageGroupCounts[j][ageIdx]++;
            }
            // 全国数据统计
            else if (j == 4){
                *nationalSum += value;
                *nationalCount += 1;
                ageGroupAverages[j*3 + ageIdx] += value;
                ageGroupCounts[j][ageIdx]++;
            }
        }
    }
    
    // 计算省份平均值
    for (int k = 0; k < 4; k++){
        if (count[k] > 0) provincialAverages[k] = sum[k] / count[k];
    }
}

// 计算并打印所有平均值
void calculateAverages(double *provincialAverages, double nationalAverage, 
                       double *yearlyAverages, int yearlyCounts[4][7], 
                       double *ageGroupAverages, int ageGroupCounts[5][3]){
    // 打印省份平均值
    printf("Provincial Averages:\n");
    printf("Ontario: %.2f%%\n", provincialAverages[0]);
    printf("Quebec: %.2f%%\n", provincialAverages[1]);
    printf("British Columbia: %.2f%%\n", provincialAverages[2]);
    printf("Alberta: %.2f%%\n\n", provincialAverages[3]);

    // 打印全国平均值
    printf("National Average: %.2f%%\n\n", nationalAverage);

    // 打印各省份年度平均值
    printf("Yearly Averages:\n");
    char *provinces[] = {"Ontario", "Quebec", "British Columbia", "Alberta"};
    for (int p = 0; p < 4; p++){
        printf("%s:\n", provinces[p]);
        for (int y = 0; y < 7; y++){
            if (yearlyCounts[p][y] > 0){
                printf("  %d: %.2f%%\n", 2015 + y, yearlyAverages[p*7 + y] / yearlyCounts[p][y]);
            }
        }
    }
    printf("\n");

    // 打印各区域年龄组平均值
    printf("Age Group Averages:\n");
    char *ageGroups[] = {"35 to 49 years", "50 to 64 years", "65 years and over"};
    char *regions[] = {"Ontario", "Quebec", "British Columbia", "Alberta", "Canada (excl. territories)"};
    for (int r = 0; r < 5; r++){
        printf("%s:\n", regions[r]);
        for (int a = 0; a < 3; a++){
            if (ageGroupCounts[r][a] > 0){
                printf("  %s: %.2f%%\n", ageGroups[a], ageGroupAverages[r*3 + a] / ageGroupCounts[r][a]);
            }
        }
    }
    printf("\n");
}

关键修复说明

  1. 变量初始化:所有统计数组、计数器都初始化为0,彻底避免垃圾值干扰。
  2. 修正内存访问错误:将nationalAverage改为累加和+计数的方式,不再当作数组访问;调整年份、年龄组数组为二维结构,清晰划分统计维度,避免越界。
  3. 优化CSV解析:跳过表头行,分步骤读取每个字段,避免重复调用strtok导致的数据错位;增加有效数据校验,只统计合法数值。
  4. 完善统计逻辑:为年份、年龄组统计增加计数变量,确保求平均时分母不为0;单独处理全国数据的累加与平均。
  5. 优化输出格式:区分不同区域的统计结果,仅输出有有效数据的平均值,避免无效输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:23:10