[英]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.