I am trying to read from a file with this text inside:
f 502 601 596 465 464
f 597 599 600 598
f 602 591 596 601
f 588 565 5
Since you have an upper bound to the number of floats, use that, but do not hard-code the 13.
Scan the file twice to determine the number of lines.
Use fgets()
to read each line.
Use sscanf()
or strtod()
to read each number. Be sure to perform error checking.
Untested code follows:
#include
#include
#include
#include
#define faces_N 13
typedef struct faces {
float p[faces_N];
} faces_T;
void foo(void) {
faces_T *eFace = NULL;
size_t Lines = 0;
FILE *fp;
fp = fopen("text.txt", "r");
if (fp == NULL)
printf("Can't open file");
else {
char buff[2*(faces_N*(FLT_DIG + 10) + 1 + 1)];
while (fgets(buff, sizeof(buff), fp) != NULL)
Lines++;
rewind(fp);
eFace = malloc(Lines * sizeof(*eFace));
assert(eFace);
for (size_t l = 0; l < Lines; l++) {
if (fgets(buff, sizeof(buff), fp) != NULL)
Handle_IOError();
if (buff[0] != 'f')
Handle_FormatError();
size_t f;
char *p = &buff[1];
for (f = 0; f < faces_N; f++) {
int n;
if (sscanf(p, "%f%n", &eFace[l].p[f], &n) != 1)
break;
p += n;
}
// TBD what to do with other
for (; f < faces_N; f++) {
eFace[l].p[f] = 0.0; // Or maybe NaN or save count in eFace
}
}
fclose(fp);
// do whatever with eFaces;
}
free(eFaces);
}
The size of buff
is debatable. I like 2x the maximum expected size and would throw an error if the buffer was full.
The number of char
to expect for a float
should be able to distinguish all float
. Estimating via " -D.DDDDDDffffde-dd"
, came up 1 (space) + 1 (sign) + 1 (.) + FLT_DIG + 3 (see link) + 4 (exponent)
. See the link for a discussion about printing precision: width specifier to maintain precision of floating-point value