我的练习是从 2 个大小未知的文件中加载 2 个矩阵,并在可能的情况下将它们相乘。我还应该加载每个文件一次。我可以通过加载文件两次来做到这一点,如下所示,但是我怎么能只加载一次文件呢?
typedef struct matrix_ {
int r, c;
double* dat;
} matrix;
int rows(char* fn) {
int lines = 1;
int ch;
FILE* fp = fopen(fn, "r");
while(!feof(fp)) {
ch = fgetc(fp);
if(ch == '\n') {
lines++;
}
}
return lines;
}
matrix loadmatrix(char* fn) {
FILE* file = fopen(fn, "r");
int size = 5*5;
matrix mat;
mat.r = rows(fn);
mat.dat = malloc(size*sizeof(double));
double input;
int i = 0;
do {
if (fscanf(file, "%lf", &input)==1) {
if(i == size-1) {
size = 4*size;
mat.dat = realloc(mat.dat, size*sizeof(double));
}
mat.dat[i] = input;
i+=1;
}
} while (!feof(file));
mat.c = ((i+1)/(mat.r));
return mat;
}
逐行读取文件,对于每一行,使用sscanf
.
每行都是一行,其中的每个值都在列中。在第一行,边走边数列,并在每个换行符处计算行数。如果您的data
数组中需要更多空间,请再realloc
增加一行的空间 ( matrix.cols * sizeof(double)
)。
使用read_line
在线路便携阅读,我们有:
#define MIN_SIZE (5 * 5)
typedef struct matrix {
size_t rows;
size_t cols;
double *data;
} matrix;
matrix loadmatrix(const char *filename)
{
FILE *file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "could not open file '%s' for reading\n", filename);
exit(1);
}
matrix mat = {
.rows = 0,
.cols = 0,
.data = calloc(MIN_SIZE, sizeof(double)),
};
// You should check mat.data != NULL here, but I omit it to ease reading
char *line = NULL;
size_t index = 0;
size_t data_size = MIN_SIZE;
while (read_line(file, &line) > 0) {
double value;
// Keep reading values into this row
size_t offset = 0;
int read_chars = 0;
while (sscanf(line + offset, "%lf%n", &value, &read_chars) == 1) {
offset += read_chars;
if (mat.rows == 0) {
++mat.cols;
}
// Increase the size of the matrix by one more row if more space is needed
if (index >= data_size) {
data_size += mat.cols;
mat.data = realloc(mat.data, sizeof(double) * data_size);
if (mat.data == NULL) {
fprintf(stderr,
"could not allocate more space for matrix: %zu\n",
data_size);
exit(1);
}
}
mat.data[index++] = value;
}
++mat.rows;
free(line);
}
return mat;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句