C语言程序读取.dad矩阵文件仅成功读取前两个值的问题
问题描述
尝试用C语言程序读取.dad文件中的3行4列矩阵:
1 3 −3 1 −1 3 2 0 2 4 0 7
但程序始终仅读取前两个值,其余元素显示为0,运行结果如下:
PS C:\Users\...\P1> gcc -o main_gauss main_gauss.c linalg.c PS C:\Users\...\P1> ./main_gauss.exe Matrix A: 1.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
无论矩阵内容如何,该现象均一致。开发环境为Visual Studio Code,相关代码如下:
main_gauss.c
#include <stdio.h> #include <math.h> #include <stdlib.h> #include "linalg.h" int main(void){ int n = 3; int m = 4; /* Allocate memory for matrix A */ double **A = (double **) malloc(n * sizeof(double *)); // Allocate memory for rows for (int i = 0; i < n; i++) { A[i] = (double *) malloc(m * sizeof(double)); // Allocate memory for columns } read_matrix(n, m, A, "Gauss1.dad"); return 0; }
linalg.c
#include "linalg.h" #include <stdio.h> #include <stdlib.h> #include <math.h> void read_matrix(int n, int m, double **A, char *s){ /* Open the file */ FILE * file ; file = fopen (s, "r"); if ( file == NULL ){ printf("Error opening %s\n", ".dad file."); return; } /* Import data to A */ printf("\nMatrix A:\n"); for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ fscanf(file, "%lf", &A[i][j]); printf("%lf ", A[i][j]); } printf("\n"); } printf ("\n"); fclose(file); // Close the file }
linalg.h
#ifndef LINALG_H #define LINALG_H void read_matrix(int n, int m, double **A, char *s); #endif
问题排查与解决方法
核心原因
文件中的负号并非ASCII标准减号(-),而是Unicode全角负号(−)。fscanf的%lf格式符仅能识别ASCII减号,遇到全角负号时会读取失败,后续读取操作因文件指针位置异常全部终止,未读取的元素保留内存初始的0值。
解决办法
方法1:修正源文件负号
直接将.dad文件中的全角负号−替换为ASCII减号-,保存后重新运行程序即可正常读取所有元素。
方法2:修改代码兼容全角负号
若无法修改源文件,可在读取逻辑中手动处理全角负号。修改linalg.c的read_matrix函数:
#include "linalg.h" #include <stdio.h> #include <stdlib.h> #include <math.h> #include <ctype.h> // 新增头文件,用于isspace函数 void read_matrix(int n, int m, double **A, char *s){ FILE * file ; file = fopen (s, "r"); if ( file == NULL ){ printf("Error opening %s\n", s); // 修正错误提示的参数问题 return; } printf("\nMatrix A:\n"); for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ int c; // 跳过所有空白字符 while ((c = fgetc(file)) != EOF && isspace(c)); if (c == EOF) break; double sign = 1.0; // 判断是否为ASCII减号或全角负号(Unicode值0x2212) if (c == '-' || c == 0x2212) { sign = -1.0; // 跳过负号,继续读取后续数字 while ((c = fgetc(file)) != EOF && isspace(c)); if (c == EOF) break; } // 将读取到的数字字符放回文件流,供fscanf读取 ungetc(c, file); double val = 0.0; if (fscanf(file, "%lf", &val) == 1) { A[i][j] = val * sign; } else { A[i][j] = 0.0; // 读取失败时设为0 } printf("%lf ", A[i][j]); } printf("\n"); } printf ("\n"); fclose(file); }
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

