#include <stdio.h>
int main() {
FILE *fp1, *fp2, *fp3;
int n, i, num, flag = 0;
/* open files to write even, odd seperately */
fp1 = fopen("data.txt", "r");
fp2 = fopen("even.txt", "w");
fp3 = fopen("odd.txt", "w");
fprintf(fp2, "Even Numbers:\n");
fprintf(fp3, "Odd Numbers:\n");
/* print even, odd and prime numbers in separate files */
while (!feof(fp1)) {
fscanf(fp1, "%d", &num);
if (num % 2 == 0) {
fprintf(fp2, "%d ", num);
} else {
if (num > 1) {
for (i = 2; i < num; i++) {
if (num % i == 0) {
flag = 1;
break;
}
}
}
fprintf(fp3, "%d ", num);
flag = 0;
}
}
fprintf(fp2, "\n");
fprintf(fp3, "\n");
fclose(fp1);
fclose(fp2);
fclose(fp3);
return 0;
}
I want to use EOF instead of feof. I have tried !EOF = fp1 but it doesn't work and gives an error. I just want to replace feof with EOF. can anyone indicate what is the problem in my code?
fscanf
returns EOF
when the end-of-file is reached:
man fscanf
#include <stdio.h> int scanf(const char *format, ...); int fscanf(FILE *stream, const char *format, ...); int sscanf(const char *str, const char *format, ...);
[...]
The
scanf()
function reads input from the standard input streamstdin
,fscanf()
reads input from the stream pointerstream
, andsscanf()
reads its input from the character string pointed to bystr
.[...]
RETURN VALUE
On success, these functions return the number of input items successfully matched and assigned; this can be fewer than provided for, or even zero, in the event of an early matching failure.
The value
EOF
is returned if the end of input is reached before either the first successful conversion or a matching failure occurs.EOF
is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, anderrno
is set to indicate the error.
A solution would be to read save the return value of fscanf
in a int
variable and check it agains 0 and EOF
, like this:
If you want to keep using fscanf
:
int ret;
while((ret = fscanf(fp1, "%d, &num)) != EOF)
{
if(ret == 0)
{
// fscanf failed to convert the input
// let it consume a charatcer and try again.
getc(fp1);
continue;
}
if(num % 2 == 0)
...
}
edit
Avoid using feof
to control looping on a file like this while(!feof(fp)
, see Why is “while ( !feof (file) )” always wrong? for more information about that.
edit 2
This was my original idea, but as Jonathan Leffler pointed out in the comments:
Jonathan Leffler wrote:
Your first solution demands a single number per line, which the code in the question does not
He's right, I didn't see that.
me from the past
One option would be to read the input line by line using
fgets
and then usesscanf
to parse the line:char buffer[1024]; while(fgets(buffer, sizeof buffer, fp1)) { if(sscanf(buffer, "%d", &num) != 1) { fprintf(stderr, "Could not read an integer, ignoring line\\n"); continue; } if (num % 2 == 0) ... }
Your condition for the while loop should be the fscanf()
statement itself. EOF
is always an integer. See the manual page for fscanf()
:
Return Value
The fscanf() function returns the number of fields that it successfully converted and assigned. The return value does not include fields that the fscanf() function read but did not assign.
The return value is EOF if an input failure occurs before any conversion, or the number of input items assigned if successful.
And, like everyone else I will refer you to Why is while ( !feof (file) )
always wrong? . This is essential reading on Stack Overflow for new C programmers.
#include <stdio.h>
int main(void) {
FILE *fp1, *fp2, *fp3;
int n, i, num, flag = 0, ret;
/* fopen files */
while ((ret = fscanf(fp1, "%d", &num)) != EOF) {
if (ret == 0) {
getc(fp1);
continue;
}
if (num % 2 == 0) {
fprintf(fp2, "%d ", num);
}
/* rest of the loop here */
}
/* fclose files */
}
If fscanf()
fails to read a character, but does not return EOF, it can often solve things to getc()
, to advance the buffer by one character. This method also works when using getchar()
to advance stdin, after getting user input from scanf()
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.