C语言中如何用fscanf正确存储矩阵及适配任意矩阵大小?
C语言读取文件中的矩阵数据
一、固定大小数组(15×5)的读取方式
直接定义二维数组,利用fscanf自动跳过空白字符的特性,无需拆分字符串即可逐个读取元素:
#include <stdio.h> int main() { int t[15][5]; int rows, cols; FILE *fp = fopen("matrix.txt", "r"); if (fp == NULL) { perror("Failed to open file"); return 1; } // 读取首行维度,可验证是否符合预期 fscanf(fp, "%d %d", &rows, &cols); if (rows != 15 || cols != 5) { printf("File matrix size does not match expected 15x5\n"); fclose(fp); return 1; } // 循环读取所有矩阵元素 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { fscanf(fp, "%d", &t[i][j]); } } fclose(fp); // 可选:打印验证读取结果 for (int i = 0; i < 15; i++) { for (int j = 0; j < 5; j++) { printf("%d ", t[i][j]); } printf("\n"); } return 0; }
二、根据文件维度动态创建数组
如果需要适配任意维度的矩阵,有两种实现方式:
方法1:使用变长数组(VLA,C99及以上支持)
直接根据读取到的维度定义数组,代码简洁:
#include <stdio.h> int main() { int rows, cols; FILE *fp = fopen("matrix.txt", "r"); if (fp == NULL) { perror("Failed to open file"); return 1; } // 读取文件首行的矩阵维度 fscanf(fp, "%d %d", &rows, &cols); // 定义变长二维数组 int t[rows][cols]; // 读取所有元素 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { fscanf(fp, "%d", &t[i][j]); } } fclose(fp); // 可选:打印验证读取结果 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { printf("%d ", t[i][j]); } printf("\n"); } return 0; }
注意:变长数组在栈上分配内存,若矩阵维度过大(如1000×1000)可能导致栈溢出,此时推荐用动态内存分配。
方法2:动态内存分配(兼容所有C标准)
通过malloc手动分配内存,避免栈溢出问题:
#include <stdio.h> #include <stdlib.h> int main() { int rows, cols; FILE *fp = fopen("matrix.txt", "r"); if (fp == NULL) { perror("Failed to open file"); return 1; } fscanf(fp, "%d %d", &rows, &cols); // 先分配存储行指针的数组 int **t = malloc(rows * sizeof(int *)); if (t == NULL) { perror("Failed to allocate memory"); fclose(fp); return 1; } // 为每行分配列内存 for (int i = 0; i < rows; i++) { t[i] = malloc(cols * sizeof(int)); if (t[i] == NULL) { perror("Failed to allocate memory"); // 释放已分配的内存,避免泄漏 for (int k = 0; k < i; k++) { free(t[k]); } free(t); fclose(fp); return 1; } } // 读取矩阵元素 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { fscanf(fp, "%d", &t[i][j]); } } // 可选:打印验证读取结果 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { printf("%d ", t[i][j]); } printf("\n"); } // 释放内存 for (int i = 0; i < rows; i++) { free(t[i]); } free(t); fclose(fp); return 0; }
以上两种动态实现中,fscanf都会自动处理空格、换行符等空白分隔符,无需逐行读取字符串再拆分。
内容的提问来源于stack exchange,提问作者joci
相关产品推荐
相关产品推荐

