1

I wrote a program to print odd and even numbers in separate files. My program is

#include<stdio.h>
int main()
{
    FILE *f1,*f2,*f3;
    int n,i,num;

    f1 = fopen("number.txt","w");
    printf("Enter the number:");
    scanf("%d",&n);
    for(i=1;i<=n;i++)
         fprintf(f1,"%d ",i);
    fprintf(f1,"\n");
    fclose(f1);

    f1 = fopen("number.txt","r");
    f2 = fopen("even.txt","w");
    f3 = fopen("odd.txt","w");

    fprintf(f2,"Even numbers:\n");
    fprintf(f3,"Odd numbers:\n");

    while(!feof(f1)){
         fscanf(f1,"%d",&num);
         if(num%2 == 0)
              fprintf(f2,"%d ",num);
         else
              fprintf(f3,"%d ",num);
    }

    fclose(f1);
    fclose(f2);
    fclose(f3);
    return 0;
}

And the output is

Enter the number:10
$ cat number.txt
1 2 3 4 5 6 7 8 9 10 

$ cat even.txt
Even numbers:
2 4 6 8 10 10 

$ cat odd.txt
Odd numbers:
1 3 5 7 9 

Why am I getting two 10s in the even output?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Tinu
  • 19
  • 4
  • possible duplicate of ["while( !feof( file ) )" is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) – Jonathan Leffler Nov 21 '14 at 07:54

3 Answers3

3

feof is true when you have read at or past the end of the file.

The scanf operation that reads 10 (the last number) will not set the eof bit because you have not tried to read at or past the end of the file yet. The loop runs again, then the eof bit is set during scanf, but you output whatever was in num before (the last number), hence the double output.

One possible fix would be to make the while loop while (true), and make the feof check immediately after fscanf, breaking if so.

fbrereto
  • 35,429
  • 19
  • 126
  • 178
1

The diagnosis by fbrereto in his answer is accurate. The prescribed fix is less satisfactory, though.

The fixed code should be:

while (fscanf(f1, "%d", &num) == 1)
{
    if (num % 2 == 0)
        fprintf(f2, "%d ", num);
    else
        fprintf(f3, "%d ", num);
}
putc('\n', f2);
putc('\n', f3);
Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0

The following is working as you expected, and it's only one line more, albeit I'm not sure it's the best and most clean way:

//
//  main.c
//  evenOdd
//

#include<stdio.h>

int main() {

    FILE *f1,*f2,*f3;
    int n,i,num;

    f1 = fopen("number.txt","w");
    printf("Enter the number:");
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        fprintf(f1,"%d ",i);
    fprintf(f1,"\n");
    fclose(f1);

    f1 = fopen("number.txt","r");
    f2 = fopen("even.txt","w");
    f3 = fopen("odd.txt","w");

    fprintf(f2,"Even numbers:\n");
    fprintf(f3,"Odd numbers:\n");

    for (i=1; !feof(f1); ++i) {
            fscanf(f1, "%d", &num);
        if (feof(f1) != 0) {return 0;} else // check if EOF
            if (num%2 == 0) {
                fprintf(f2, "%d ", num);
            } else fprintf(f3, "%d ", num);
        }


    fclose(f1);
    fclose(f2);
    fclose(f3);
    return 0;
}
sabi
  • 423
  • 2
  • 8
  • It is much better to test the I/O function (`fscanf()` in this case) than to use `feof()`. You use `feof()` after you've already spotted a problem to distinguish between EOF and an error (`ferror()` tells you it was an error). But that's the only legitimate use of `feof()`. Loop controls or double-testing `feof()` are clumsy at best and more usually erroneous. – Jonathan Leffler Nov 21 '14 at 08:37