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

C语言读取无表头三列数据绘制柱状图遇重复及数值错误问题

问题分析与修复方案

嘿,我看了你这段代码,问题主要出在数据读取和柱状图绘制的逻辑上,咱们一步步捋清楚:

核心问题点

1. 不必要的循环导致柱子重复

你在处理每一行数据时加了一个for(int j=0;j<3;j++)循环,这会让同一行数据重复调用3次appendBar,自然就出现了重复的柱子。这完全没必要,因为每行就是一组3列数据,只需要处理一次就行。

2. strtok的误用与冗余代码

你先是用strtok按\n分割每行,但fgets已经把每行单独存在line[i]里了,这步操作完全多余。而且后面又用sscanf直接读取整行数据,前面的strtok和strncpy都是无效操作,还容易搞乱数据解析。

3. 文件关闭时机错误

你把fclose(fptr)放在了waitExit()之后,而waitExit()应该是阻塞等待用户退出的函数,这时候文件句柄一直没关闭,属于资源泄漏,应该把它移到读取完文件之后的位置。

修复后的完整代码

#include "visualiser.h"
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <unistd.h>
#define LSIZ 128
#define RSIZ 10

void passFile(char *arr);

int main(int argc, char **argv){
    initInterface("silver","blue");
    if(argc <2){
        passFile("data-file.txt");
    } else if(argc == 2){ // 改成else if,避免多分支判断的逻辑漏洞
        passFile(argv[1]);
    } else {
        printf("Invalid arguments");
        exit(0);
    }
    return 0;
}

void passFile(char *arr){
    char line[RSIZ][LSIZ];
    int i = 0;
    int tot = 0;
    FILE *fptr = NULL;

    fptr = fopen(arr, "r");
    if(fptr == NULL){ // 增加文件打开失败的判断,避免空指针错误
        perror("Failed to open file");
        exit(1);
    }

    // 读取所有行到数组
    while(fgets(line[i], LSIZ, fptr)){
        // 安全去除换行符(兼容无换行符的行)
        size_t len = strlen(line[i]);
        if(len > 0 && line[i][len-1] == '\n'){
            line[i][len-1] = '\0';
        }
        i++;
    }
    tot = i;
    fclose(fptr); // 读取完文件就关闭,避免资源泄漏

    printf("\n The content of the file %s are : \n",arr);
    for(i = 0; i < tot; ++i){
        char name[18];
        int arrivalTime;
        int serviceTime;

        // 直接用sscanf解析整行的3列数据
        if(sscanf(line[i], "%17s %d %d", name, &arrivalTime, &serviceTime) == 3){
            appendRow(name); // 传入第一列的名称
            appendBar(i+1, serviceTime, "black", " ", 0); // 只调用一次,绘制对应柱子
            printf("Row: %s, Arrival: %d, Service: %d\n", name, arrivalTime, serviceTime); // 可选:打印调试信息
        } else {
            printf("Invalid line format: %s\n", line[i]); // 处理格式错误的行
        }
    }
    printf("\n");

    sleep(100);
    waitExit();
}

额外优化说明

  • 增加了文件打开失败的判断,避免空指针访问导致崩溃;
  • 改进了换行符的去除逻辑,避免行尾没有换行符时修改字符串的错误;
  • 把main里的分支改成else if,避免原代码中argc<2和argc==2都可能执行的逻辑漏洞;
  • 增加了格式错误行的处理,方便调试不符合3列格式的行。

这样修改后,每行数据只会被解析一次,正确读取第三列的serviceTime来绘制柱状图,柱子重复和数值错误的问题就解决了。

内容的提问来源于stack exchange,提问作者wak.igo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:15:33