Reputation: 13
So, I have a file like this:
12345 name1 18 500.000000
12345 name2 18 500.000000
And I wanted to read the file and each column go to a different variable. So I coded this:
void updateStruct() {
char c;
int lines, i;
accounts account[accMAX];
FILE *acc = fopen("acc.dat", "r+");
if (acc == NULL)
return;
for (c = getc(acc); c != EOF; c = getc(acc))
if (c == '\n')
lines += 1;
fscanf(acc, "%d %s %d %f", &account[0].number, account[0].name,
&account[0].age, &account[0].balance);
}
Somehow, the fscanf()
doesn't attribute any value to the variables. What am I doing wrong?
Upvotes: 1
Views: 38
Reputation: 145297
The for
loop to compute the number of lines reads the whole file. fscanf()
fails to convert anything and returns EOF
.
You must rewind the position to the beginning of file with rewind(acc)
or fseek(acc, 0L, SEEK_SET)
.
Note also that variable c
must have type int
for the EOF
test to function correctly. Furthermore you should also count the last line that may or may not have a newline.
Here is a modified version:
accounts *updateStruct(int *countp) {
int c, last, lines, i;
FILE *acc = fopen("acc.dat", "r");
if (acc == NULL)
return NULL;
last = EOF;
while ((c = getc(acc)) != EOF) {
if (c == '\n')
lines += 1;
last = c;
}
if (last != '\n') { // last line did not have a newline
lines += 1;
}
rewind(acc);
accounts *account = calloc(lines, sizeof(account));
if (account == NULL) {
fclose(acc);
return NULL;
}
for (i = 0; i < count;) {
if (fscanf(acc, "%d %s %d %f", &account[i].number, account[i].name,
&account[i].age, &account[i].balance) != 4) {
// invalid line: skip to the newline
while ((c = getc(acc)) != EOF && c != '\n')
continue;
if (c == EOF)
break;
} else {
i++;
}
}
fclose(acc);
*countp = i;
return account;
}
Upvotes: 0
Reputation: 14044
The for
loop leaves the file pointer at the end of the file. Call rewind
to position the file pointer back at the start of the file before calling fscanf
.
Upvotes: 1