Прочитайте файл построчно, и для каждой строки прочитайте в каждом значении с 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;
}