[英]Reading Complex Matrix From Text File
我在尝试从 C 中的文本文件中读取复杂矩阵时遇到了很多麻烦。文本文件的格式为(%le%+lej)
形式。 使用的测试矩阵是:
(0.000000000000000000e+00+0.000000000000000000e+00j) (0.000000000000000000e+00+1.000000000000000056e-01j) (0.000000000000000000e+00+2.000000000000000111e-01j) (0.000000000000000000e+00+3.000000000000000444e-01j)
(1.100000000000000089e+00+0.000000000000000000e+00j) (1.100000000000000089e+00+1.000000000000000056e-01j) (1.100000000000000089e+00+2.000000000000000111e-01j) (1.100000000000000089e+00+3.000000000000000444e-01j)
(2.200000000000000178e+00+0.000000000000000000e+00j) (2.200000000000000178e+00+1.000000000000000056e-01j) (2.200000000000000178e+00+2.000000000000000111e-01j) (2.200000000000000178e+00+3.000000000000000444e-01j)
我花了将近两天的时间才试图让它工作。 所以如果存在这样的事情,我想要一个简单易调试的解决方案。
我的简化尝试:
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
int main(void)
{
char fname[] = "test_matrix.dat";
int m = 3;
int n = 4;
complex double * matrix = calloc(m * n, sizeof(complex double));
FILE * ifile = fopen(fname, "r");
int i, j, info;
double zreal, zimag;
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
info = fscanf(ifile, "(%le%lej)", &zreal, &zimag);
// The following doesn't work either.
// info = fscanf(ifile, "(%le", &zreal);
// info += fscanf(ifile, "%lej)", &zimag);
if(info != 2)
{
fclose(ifile);
fprintf(stderr, "Wrong input format, info = %d\n", info);
exit(EXIT_FAILURE);
}
*(matrix + i + j*m) = zreal + I*zimag;
// printf("%d ", info); This gives all zeroes
printf("%6.1e%+7.1ej ", zreal, zimag);
}
printf("\n");
}
fclose(ifile);
free(matrix);
return(0);
}
我也尝试过不在fscanf
中放置额外的格式化内容,而是尝试循环fgetc
直到我阅读(
然后执行两个fscanf
s,但它很快变得太复杂且难以调试,仍然无法得到它工作。因此,我们将不胜感激。
编辑:这与问题无关,但只是为了澄清我正在使用列主要格式,因为它必须在以后与 blas/lapack 一起使用。
fscanf
格式不正确:
info = fscanf(ifile, " (%le+%lej)", &zreal, &zimag);
既然您提出了要求,我想通过提供一个完整的工作示例来补充Fryz的回答:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <complex.h>
int main(void)
{
const char *filename = "test_matrix.dat";
FILE *file = fopen(filename, "r");
if (!file) {
perror("Could not open file");
return 1;
}
const size_t nrows = 3;
const size_t ncols = 4;
complex double *matrix = malloc(nrows * ncols * sizeof(*matrix));
if (!matrix) {
printf("Internal error\n");
fclose(file);
return 1;
}
double zreal, zimag;
for (size_t i = 0; i < nrows; ++i) {
for (size_t j = 0; j < ncols; ++j) {
if (fscanf(file, " (%le+%lej)", &zreal, &zimag) != 2) {
printf("%zu::%zu: Wrong format\n", i, j);
continue;
}
matrix[i+j*ncols] = zreal + I * zimag;
printf("(%.18le+%1.18lej) ", zreal, zimag);
}
printf("\n");
}
free(matrix);
fclose(file);
}
Output:
(0.000000000000000000e+00+0.000000000000000000e+00j) (0.000000000000000000e+00+1.000000000000000056e-01j) (0.000000000000000000e+00+2.000000000000000111e-01j) (0.000000000000000000e+00+3.000000000000000444e-01j)
(1.100000000000000089e+00+0.000000000000000000e+00j) (1.100000000000000089e+00+1.000000000000000056e-01j) (1.100000000000000089e+00+2.000000000000000111e-01j) (1.100000000000000089e+00+3.000000000000000444e-01j)
(2.200000000000000178e+00+0.000000000000000000e+00j) (2.200000000000000178e+00+1.000000000000000056e-01j) (2.200000000000000178e+00+2.000000000000000111e-01j) (2.200000000000000178e+00+3.000000000000000444e-01j)
需要注意的几点:
const
。size_t
,而不是int
。以下代码在我的计算机上成功运行,输入如下:
#include <stdio.h>
int main()
{
double x, y;
int res;
while ((res = fscanf(stdin, "(%lg%lgj)", &x, &y)) == 2) {
printf("(%g, %g)", x, y);
}
printf("res == %d\n", res);
}
和以下输入:
$ a.out
(3-5j)(2-8j)(-6+3j) <-- input
(3, -5)(2, -8)(-6, 3)res == 0 <-- output
$ _
正如您可能猜到的那样,当我按下回车键时,输入不匹配,我读取了三个有效的复数,之后没有任何匹配( fscanf()
得到一个\n
字符,并且没有读取任何内容,返回0 到 while 循环。我打印了 function 的结果以查看它失败的原因。我的建议是在输入之间你应该自己处理空格(以便在扫描\n
时也能区分)。
更好的格式是为矩阵维度扫描两个数字,然后为矩阵内容rows*cols
对数字,所有这些都由任何类型的空格分隔。 例如
2 2
1 0 0 0
0 0 1 0
这将导致从输入文件中读取单位矩阵。
对于更精细的阅读器,您将需要从flex(1)
和/或bison(1)
工具中获得帮助,这些工具允许您处理空格甚至注释或嵌套括号:,。 :) 这些工具的编写是为了帮助您全面解析复杂的语言,例如 C 或 pascal。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.