如何从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
相关产品推荐
相关产品推荐

