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

C语言实现逗号分隔数据文件到指定exp格式文件转换

C语言实现data格式文件转exp格式文件

需求说明

输入文件为datafile.data,每行由逗号分隔的整数组成:前n列为属性值,最后1列为类别值,属性数量n可随文件动态变化。需要输出outputfile.exp文件满足以下要求:

  • 输出文件首行依次填入:原文件行数、属性数量、各属性的最大值、类别最大值+1,所有数值用空格分隔
  • 剩余行与原文件一一对应,仅做两处修改:逗号分隔符替换为空格,最后一列的数值统一加1

完整实现代码

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

#define MAX_LINE_LEN 1024
#define MAX_ATTRS 128 // 可根据实际属性数量调整上限

int main()
{
    FILE *fp_in, *fp_out;
    int line_count = 0;
    int attr_count = 0;
    int attr_max[MAX_ATTRS];
    int class_max = INT_MIN;
    char line_buf[MAX_LINE_LEN];

    // 初始化属性最大值为最小整型
    for (int i = 0; i < MAX_ATTRS; i++) {
        attr_max[i] = INT_MIN;
    }

    // 第一遍读文件:统计行数、属性数、各属性最大值、类别最大值
    fp_in = fopen("datafile.data", "r");
    if (fp_in == NULL) {
        printf("无法打开输入文件datafile.data\n");
        return 1;
    }

    while (fgets(line_buf, MAX_LINE_LEN, fp_in) != NULL) {
        // 跳过空行
        if (line_buf[0] == '\n' || line_buf[0] == '\r') continue;
        
        line_count++;
        int col_idx = 0;
        int num = 0;
        char *p = line_buf;

        // 逐数字解析当前行
        while (*p != '\0' && *p != '\n' && *p != '\r') {
            // 读取整数
            if (*p >= '0' && *p <= '9') {
                num = num * 10 + (*p - '0');
            }
            // 遇到逗号或者行尾,处理当前数值
            if (*p == ',' || *(p+1) == '\0' || *(p+1) == '\n' || *(p+1) == '\r') {
                // 第一行确定属性数量:总列数-1
                if (line_count == 1) {
                    attr_count++;
                }
                // 是属性列
                if (col_idx < attr_count - 1) {
                    if (num > attr_max[col_idx]) {
                        attr_max[col_idx] = num;
                    }
                } 
                // 是类别列
                else {
                    if (num > class_max) {
                        class_max = num;
                    }
                }
                col_idx++;
                num = 0;
            }
            p++;
        }
    }
    // 第一行读出来的是总列数,属性数=总列数-1
    attr_count = attr_count - 1;
    fclose(fp_in);

    // 第二遍读文件:写入输出文件
    fp_in = fopen("datafile.data", "r");
    fp_out = fopen("outputfile.exp", "w");
    if (fp_in == NULL || fp_out == NULL) {
        printf("文件打开失败\n");
        return 1;
    }

    // 写首行
    fprintf(fp_out, "%d %d ", line_count, attr_count);
    for (int i = 0; i < attr_count; i++) {
        fprintf(fp_out, "%d ", attr_max[i]);
    }
    fprintf(fp_out, "%d\n", class_max + 1);

    // 写剩余行
    while (fgets(line_buf, MAX_LINE_LEN, fp_in) != NULL) {
        if (line_buf[0] == '\n' || line_buf[0] == '\r') continue;
        
        int col_idx = 0;
        int num = 0;
        char *p = line_buf;
        while (*p != '\0' && *p != '\n' && *p != '\r') {
            if (*p >= '0' && *p <= '9') {
                num = num * 10 + (*p - '0');
            }
            if (*p == ',' || *(p+1) == '\0' || *(p+1) == '\n' || *(p+1) == '\r') {
                // 最后一列要加1
                if (col_idx == attr_count) {
                    num += 1;
                }
                fprintf(fp_out, "%d", num);
                // 不是最后一个数就加空格
                if (*p == ',') {
                    fprintf(fp_out, " ");
                }
                col_idx++;
                num = 0;
            }
            p++;
        }
        fprintf(fp_out, "\n");
    }

    fclose(fp_in);
    fclose(fp_out);
    printf("转换完成,已生成outputfile.exp\n");
    return 0;
}

实现说明

  • 代码分两次遍历输入文件:第一次遍历统计所有需要写入首行的元数据,第二次遍历完成内容转换和输出
  • 未使用复杂的字符串拆分函数,逻辑清晰适合C语言初学者理解
  • 可通过修改MAX_ATTRS和MAX_LINE_LEN宏适配更大的文件和更多属性的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:15:04