You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C语言作业求助:从TXT读取车辆数据并实现统计及处罚文件生成

Hey there! 作为车辆工程专业的同学,零基础啃C语言作业确实有点懵,不过别慌,我会把这个任务拆成一步步的,代码写得明明白白,带你顺利完成~

你的C语言作业全流程实现(零基础友好版)

我会用结构体数组来存储车辆记录(比你提到的矩阵更贴合这个场景,因为每条记录是不同类型的数据:字符串+整数,结构体能把它们打包在一起,处理起来更顺手),然后逐个实现你的需求。

一、先搭好基础:定义数据结构

首先我们需要一个结构体,把每条车辆的车牌、日期、时间、速度都装进去:

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

// 定义车辆记录的结构体,把每条数据打包
typedef struct {
    char license_plate[10];  // 存车牌(比如AAA-111),长度足够用
    char date[11];           // 存日期(比如2019.01.01),算上结束符共11位
    char time[6];            // 存时间(比如12:12),算上结束符共6位
    int speed;               // 存速度(整数)
} VehicleRecord;

二、第一步:读取TXT文件的数据

假设你的输入文件名叫traffic_data.txt,每行格式是AAA-111 2019.01.01 12:12 50(空格分隔),用fscanf读取比你之前尝试的逐字符读取简单太多:

// 读取文件,返回读取到的记录总数
int read_traffic_data(const char* filename, VehicleRecord records[], int max_records) {
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        printf("打不开文件 %s!检查一下文件路径对不对~\n", filename);
        return 0;
    }

    int count = 0;
    // 按格式读取每一行,直到文件结束
    while (fscanf(file, "%s %s %s %d", 
                  records[count].license_plate,
                  records[count].date,
                  records[count].time,
                  &records[count].speed) != EOF && count < max_records) {
        count++;
    }

    fclose(file);
    return count;
}

小解释:

  • fopen是打开文件,"r"表示只读模式
  • fscanf会自动按空格分割数据,直接把对应的值塞进结构体里,不用自己手动拆分字符,省超多事

三、第二步:统计同一日期的通行车辆数量

我们可以遍历所有记录,先给日期去重,再逐个统计每个日期的车辆数:

void count_daily_vehicles(VehicleRecord records[], int total_records) {
    printf("\n=== 每日通行车辆统计 ===\n");
    
    // 存已经统计过的日期,避免重复计算
    char processed_dates[100][11];  // 假设最多100个不同日期,不够可以改数字
    int date_count = 0;

    for (int i = 0; i < total_records; i++) {
        // 检查当前日期是不是已经统计过了
        int is_processed = 0;
        for (int j = 0; j < date_count; j++) {
            if (strcmp(records[i].date, processed_dates[j]) == 0) {
                is_processed = 1;
                break;
            }
        }

        if (!is_processed) {
            // 统计这个日期的车辆总数
            int daily_count = 0;
            for (int k = 0; k < total_records; k++) {
                if (strcmp(records[i].date, records[k].date) == 0) {
                    daily_count++;
                }
            }
            // 把这个日期加入已统计列表
            strcpy(processed_dates[date_count], records[i].date);
            date_count++;
            // 打印结果
            printf("日期 %s:通行 %d 辆车\n", records[i].date, daily_count);
        }
    }
}

小解释:

  • strcmp是字符串比较函数,返回0就表示两个日期完全一样
  • 外层循环遍历每条记录,内层先判断日期是否已统计,没统计过就遍历所有记录数总数

四、第三步:根据用户输入的阈值,计算超速车辆占比

这个很简单,先让用户输入阈值,再统计超速数量,最后算占比:

void calculate_speeding_ratio(VehicleRecord records[], int total_records) {
    int speed_threshold;
    printf("\n请输入速度阈值:");
    scanf("%d", &speed_threshold);

    int speeding_count = 0;
    for (int i = 0; i < total_records; i++) {
        if (records[i].speed > speed_threshold) {
            speeding_count++;
        }
    }

    // 用浮点数计算占比,避免整数除法得到0
    float ratio = (float)speeding_count / total_records * 100;
    printf("超速车辆共 %d 辆,占比 %.2f%%\n", speeding_count, ratio);
}

五、第四步:生成speeding文件,记录罚款信息并统计受处罚车辆数

先按你说的规则设置罚款区间,比如:

  • 超速区间50-60:罚款100美元
  • 超速区间60-80:罚款200美元
  • 超速超过80:罚款500美元
    你可以根据作业要求直接修改规则:
int generate_speeding_file(VehicleRecord records[], int total_records, int speed_threshold) {
    FILE* file = fopen("speeding.txt", "w");
    if (file == NULL) {
        printf("无法创建speeding文件!\n");
        return 0;
    }

    // 先写文件表头
    fprintf(file, "车牌\t日期\t罚款金额(美元)\n");
    
    int penalty_count = 0;
    for (int i = 0; i < total_records; i++) {
        if (records[i].speed > speed_threshold) {
            int fine = 0;
            // 根据超速区间确定罚款金额,这里可以按需修改
            if (records[i].speed > speed_threshold && records[i].speed <= speed_threshold + 10) {
                fine = 100;
            } else if (records[i].speed > speed_threshold + 10 && records[i].speed <= speed_threshold + 30) {
                fine = 200;
            } else if (records[i].speed > speed_threshold + 30) {
                fine = 500;
            }

            // 把信息写入文件
            fprintf(file, "%s\t%s\t%d\n", records[i].license_plate, records[i].date, fine);
            penalty_count++;
        }
    }

    fclose(file);
    printf("\n已生成speeding文件,受处罚车辆共 %d 辆\n", penalty_count);
    return penalty_count;
}

小解释:

  • fopen("speeding.txt", "w")是创建/覆盖文件,写入模式
  • fprintfprintf用法一样,只是把内容写到文件里,不是屏幕上

六、主函数:把所有功能串起来

最后写主函数,调用上面的所有功能,这里假设最多存1000条记录(数据多的话改数字就行):

int main() {
    VehicleRecord records[1000];  // 存储最多1000条车辆记录
    int total_records = read_traffic_data("traffic_data.txt", records, 1000);

    if (total_records == 0) {
        printf("没有读取到任何数据!检查一下输入文件是否正确~\n");
        return 1;
    }

    // 依次执行各个功能
    count_daily_vehicles(records, total_records);
    
    int threshold;
    printf("\n请输入速度阈值:");
    scanf("%d", &threshold);
    calculate_speeding_ratio(records, total_records);
    
    generate_speeding_file(records, total_records, threshold);

    return 0;
}

给你的零基础小提示

  1. 把所有代码复制到一个.c文件里,比如traffic_analysis.c
  2. 编译用gcc traffic_analysis.c -o traffic_analysis(如果用GCC编译器)
  3. 输入文件traffic_data.txt要和编译后的程序放在同一个文件夹,每行格式要正确(比如AAA-111 2019.01.01 12:12 50
  4. 如果报错,先检查文件路径、输入格式是不是对的

内容的提问来源于stack exchange,提问作者Krisztián Kővári

火山引擎 最新活动