I am having a lot of trouble trying to read a complex matrix from a text file in C. The format of the text file is of the form (%le% lej)
. The test matrix used is:
(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)
I have spent nearly two days just trying to get this working. So I would like a simple and easy to debug solution if such a thing exists.
My simplified attempt:
#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);
}
I have also tried not putting the extra formatting things in the fscanf
, instead I tried looping fgetc
till I read (
and then doing two fscanf
s, but it quickly became too complicated and hard to debug, still haven't been able to get that working. So any assistance will be appreciated.
EDIT: This is irrelevant to the problem, but just to clarify I am using column major format because it has to be used with blas/lapack later on.
CodePudding user response:
fscanf
format is not correct :
info = fscanf(ifile, " (%le %lej)", &zreal, &zimag);
CodePudding user response:
Since you requested it, I'd like to add to Fryz's answer by providing a complete working example:
#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)
Few things to note:
- Always check the return value of C standard library functions.
- Use
const
when a variable's value will not be changed. - The appropriate type for indices is
size_t
, notint
. - Close your file handles and free your allocated memory when you are done with them.