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

如何从txt文件中提取float元素填充C语言动态二维float数组

功能实现方案

原有代码核心问题

  • 内存分配错误:首行分配指针数组时参数错误,应为sizeof(float*),原代码写的sizeof(float)会导致指针数组空间不足,直接触发内存越界崩溃
  • 逻辑顺序错误:必须先遍历一次所有有效数据行,拿到每行的数值计数字段的最大值,算出num_columns = 最大计数值 + 1后,才能分配二维数组的内存,否则无法确定需要开辟的列数
  • 读取细节问题:strtok的分隔符未包含换行符,会导致行尾的0.00携带换行符转换出错;直接用==判断浮点数等于0.00存在精度误差风险,应判断浮点数绝对值小于极小阈值

完整实现代码

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

#define BUF_SIZE 1024
#define EPS 1e-6

int main() {
    FILE* fp = fopen("data.txt", "r");
    if (fp == NULL) {
        perror("文件打开失败");
        return 1;
    }

    char buf[BUF_SIZE];
    int n, num_lines, num_columns = 0;

    // 第一步:读首行获取有效行数
    fgets(buf, BUF_SIZE, fp);
    n = atoi(buf);
    num_lines = n + 1;

    // 第二步:第一次遍历所有有效行,获取最大列数
    long first_data_pos = ftell(fp); // 记录首行之后的文件偏移
    for (int i = 0; i < num_lines; i++) {
        fgets(buf, BUF_SIZE, fp);
        // 遇到(null)提前终止
        if (strstr(buf, "(null)") != NULL) break;
        // 跳过姓名字段
        strtok(buf, " \n");
        // 读取当前行的数值计数
        int cur_col = atoi(strtok(NULL, " \n"));
        if (cur_col + 1 > num_columns) {
            num_columns = cur_col + 1;
        }
    }

    // 第三步:正确分配二维float数组
    float** M = (float**)malloc(num_lines * sizeof(float*));
    for (int i = 0; i < num_lines; i++) {
        M[i] = (float*)malloc(num_columns * sizeof(float));
        // 初始化为0避免未定义行为
        memset(M[i], 0, num_columns * sizeof(float));
    }

    // 第四步:回滚文件指针,第二次遍历加载float数据
    fseek(fp, first_data_pos, SEEK_SET);
    for (int i = 0; i < num_lines; i++) {
        fgets(buf, BUF_SIZE, fp);
        if (strstr(buf, "(null)") != NULL) break;
        // 跳过姓名字段
        strtok(buf, " \n");
        // 跳过当前行计数字段
        strtok(NULL, " \n");
        // 循环读取float直到遇到0.00
        for (int j = 0; j < num_columns; j++) {
            char* val_str = strtok(NULL, " \n");
            if (val_str == NULL) break;
            float val = atof(val_str);
            if (fabs(val - 0.00) < EPS) {
                break;
            }
            M[i][j] = val;
        }
    }

    // 这里可以加测试代码,打印数组验证结果
    for (int i = 0; i < num_lines; i++) {
        printf("第%d行:", i+1);
        for (int j = 0; j < num_columns; j++) {
            printf("%.2f ", M[i][j]);
        }
        printf("\n");
    }

    // 释放内存
    for (int i = 0; i < num_lines; i++) {
        free(M[i]);
    }
    free(M);
    fclose(fp);
    return 0;
}

补充说明

  • 代码中用ftell和fseek实现文件指针的回滚,避免多次打开文件的开销
  • 所有字符串分割时都把\n加入分隔符,避免换行符干扰数值转换
  • 分配内存后先做了初始化操作,避免未填充的位置出现随机值
  • 浮点数判断相等使用了精度阈值EPS,避免精度误差导致0.00判断失效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:54:03