Reputation: 671
I currently have code that reads 4 lines and I want to be able to change that until EOF or my MAX const int value. I can not get the !EOF to work right and was wondering how would I change my code to accomplish this?
Thanks in advance
#include <stdio.h>
struct record{
char name[2];
int arrival_time;
int job_length;
int job_priority;
};
const int MAX = 40;
int main(void)
{
struct record jobs[MAX];
int i = 0;
int j;
FILE *f = fopen("data.dat","rb");
while (fscanf(f, "%s %d %d %d", &jobs[i].name, &jobs[i].arrival_time,
&jobs[i].job_length, &jobs[i].job_priority) == 4 && i < MAX)
i++;
for (j = 0; j < i; j++)
printf("%s %d %d %d\n", jobs[j].name, jobs[j].arrival_time,
jobs[j].job_length, jobs[j].job_priority);
fclose(f);
return(0);
}
Upvotes: 5
Views: 84681
Reputation: 13
Personnaly, I would code like this:
for(i=0 ; i<MAX ; ++i) {
fscanf(f, "%s %d %d %d", &jobs[i].name, &jobs[i].arrival_time,
&jobs[i].job_length, &jobs[i].job_priority);
if(ferror(f) || feof(f)) break;
}
The key point is that, at the best of my knowledge, you cannot know that a file is come to end without trying to read it. That is the reason why I check feof() and ferror() after having read data. At the end of the loop, the variable i contains the number of read data
Upvotes: 1
Reputation: 96109
Something like
while (fscanf(f, " %s ", &etc) != EOF) {
}
Then use feof(f)
to check if it was a fscanf
error or actually EOF
.
Upvotes: 8
Reputation: 239041
You need to change the order of the tests in your while()
loop - you must test i < MAX
before calling fscanf()
, or else you'll potentially call it one too many times (you should also be passing jobs[i].name
without the &
to fscanf
):
while (i < MAX && fscanf(f, "%s %d %d %d", jobs[i].name, &jobs[i].arrival_time,
&jobs[i].job_length, &jobs[i].job_priority) == 4)
Upvotes: 1
Reputation: 18320
Your code seems to do what you want, except:
char name[2];
Names will probably be longer than 1 character.
FILE *f = fopen("data.dat","rb");
You seem to be reading text ("r"
) file, not binary ("rb"
).
&jobs[i].name
should be jobs[i].name
Upvotes: 2