C语言如何实现从文件读取任意大小n×n方阵的浮点数?
改造C语言矩阵读取代码,支持任意大小n×n方阵
我来帮你把这段固定3×3的矩阵读取代码改成支持任意大小的动态版本。核心要解决两个问题:自动确定矩阵的阶数n,以及动态分配对应大小的内存空间。咱们一步步来改:
核心思路拆解
- 先确定n的值:因为输入文件是恰好能组成n×n方阵的数字,所以先统计文件里的总数字个数,取平方根就得到n(比如总共有9个数字就是3×3,16个就是4×4)。
- 动态分配二维数组:C里没法直接定义大小可变的二维数组,所以用指针的指针(
float **)来实现,或者用一维数组模拟二维访问(更高效)。 - 通用读取逻辑:不再写死3×3的读取格式,用循环读取所有数字,自动跳过逗号和换行符。
修改后的完整代码
#include <stdio.h> #include <stdlib.h> #include <math.h> // 用于sqrt函数 // 动态分配矩阵并读取文件,返回矩阵的阶数n,矩阵指针通过参数传出 int ReadMatrix(float ***matrix, const char *filename) { FILE *f_pointer = fopen(filename, "r"); if (f_pointer == NULL) { printf("Error: 文件未找到"); return -1; } // 第一步:统计文件中的数字总数 float temp; int count = 0; // 读取所有数字,忽略逗号(用%f读取时,会自动跳过空白符,逗号需要单独处理) while (fscanf(f_pointer, "%f", &temp) == 1) { count++; // 跳过后面的逗号(如果有的话,最后一个数字后可能没有逗号,不影响) fscanf(f_pointer, ","); } // 计算矩阵阶数n,确保是完全平方数(题目说输入是方阵,这里加个校验更稳妥) int n = sqrt(count); if (n * n != count) { printf("Error: 输入数字个数不是完全平方数,无法组成方阵"); fclose(f_pointer); return -1; } // 第二步:动态分配二维矩阵 *matrix = (float **)malloc(n * sizeof(float *)); if (*matrix == NULL) { printf("Error: 内存分配失败"); fclose(f_pointer); return -1; } for (int i = 0; i < n; i++) { (*matrix)[i] = (float *)malloc(n * sizeof(float)); if ((*matrix)[i] == NULL) { // 如果某行分配失败,要释放之前已分配的内存,避免泄漏 for (int j = 0; j < i; j++) { free((*matrix)[j]); } free(*matrix); printf("Error: 内存分配失败"); fclose(f_pointer); return -1; } } // 第三步:重新定位文件指针到开头,读取数据到矩阵 rewind(f_pointer); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { fscanf(f_pointer, "%f", &(*matrix)[i][j]); // 跳过逗号 fscanf(f_pointer, ","); } } fclose(f_pointer); return n; } // 测试主函数 int main() { float **A; int n = ReadMatrix(&A, "Input Matrix.txt"); if (n == -1) { return 1; } // 打印矩阵验证读取结果 printf("读取的%d×%d矩阵:\n", n, n); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { printf("%.2f ", A[i][j]); } printf("\n"); } // 释放动态分配的内存,避免内存泄漏 for (int i = 0; i < n; i++) { free(A[i]); } free(A); return 0; }
关键改动说明
- 去掉固定数组:不再定义
float A[3][3],改用float **动态分配,矩阵大小完全由输入文件的数字个数决定。 - 统计数字个数:先遍历文件一次统计总数字数,计算出n。这里
fscanf("%f")会自动跳过换行等空白符,再用fscanf(",")跳过数字间的逗号,适配文件的换行格式。 - 内存安全处理:分配二维数组时做了容错,如果某行分配失败,会释放之前已分配的内存;使用完矩阵后也会逐层释放,避免内存泄漏。
- 通用读取逻辑:用双层循环读取n×n个数字,不再写死3×3的格式,不管n是多少都能正常读取。
注意事项
- 编译时需要链接数学库,比如GCC编译要加
-lm参数:gcc your_code.c -o matrix_reader -lm。 - 如果输入文件的数字分隔符不是逗号,只需要修改
fscanf(",")里的分隔符即可。 - 代码里的校验逻辑可以确保输入符合方阵要求,避免程序异常。
内容的提问来源于stack exchange,提问作者Shashank Saumya
相关产品推荐
相关产品推荐

