1

I made a program to count number in input.txt:

input.txt

13 1 17 3 14 10 18 18 16 13 15 5 5 6 12 8 8 3 2 5 4 10 11 3 1 5 10 1 7 5 6 10 9 4 3 10 15 13

main.c

#include<stdio.h>

int main()
{
    FILE *fptr;
    fptr=fopen("input.txt","r");
    int data;
    int count=0;
    while(!feof(fptr))
    {
        fscanf(fptr,"%d",&data);
        count++;
    }
    printf("%d",count);
}

And the result is infinite character 'p' ???

https://i.stack.imgur.com/oXlv8.jpg

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • How are you compiling? Looks good to me. – LionsFan Dec 23 '17 at 03:50
  • I use DevC++ 5.11 with -std=c99 and -static-libgcc –  Dec 23 '17 at 03:54
  • 2
    Fyi, replace `!feof(fptr)` in your while condition with `fscanf(fptr, "%d", &data) == 1`, then throw out the `fscanf` call within the loop body. Read: [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) to better understand why. Regarding your infinite output, that's a neat trick, since this code has no output statements within a loop. How about testing `fptr` to make sure you opened the file rather than assuming it worked. Assumption is the mother of all... – WhozCraig Dec 23 '17 at 04:14
  • never use `while( !feof(..) )` because `feof()` does not work the way you think it does, When calling system functions, like `fopen()`, always check (!=NULL) the returned value to assure the operation was successful. – user3629249 Dec 24 '17 at 03:50
  • when calling any of the `scanf()` family of functions: always check the returned value (not the parameter values) to assure the operation was successful. – user3629249 Dec 24 '17 at 03:52
  • a program should always cleanup after itself. in the current scenario, there should be the statement: `fclose( fptr ); just before exiting main. – user3629249 Dec 24 '17 at 03:53

2 Answers2

1

This works:

#include <stdio.h>

int main(void) {
    FILE *fptr;
    if (!(fptr = fopen("input.txt", "r"))) {
        printf("Could not open file\n");
        return 1;
    }
    int data, count;
    for (count = 0; fscanf(fptr, "%d ", &data) == 1; count++)
        ;

    printf("%d\n", count);
    fclose(fptr);
    return 0;
}

Please note the following adjustments I made to your code.

  • You did not do any error checking to see if "input.txt" exists or not. You should not write code, even for small programs, that assumes things like that. This program now prints an error message and returns 1 to the shell, if the input file doesn't exist.

  • while (!feof(fptr)) is bad practice, and often doesn't work. To check if there is remaining data in the file, use the scanf() statement itself as the loop conditional. I made it a for loop for ease and efficiency.

  • You did not perform fclose() on your file pointer. This is absolutely necessary, as you don't want a file pointer floating around in memory, and you want your system/shell to know that file is no longer in use.

  • int main() should always return 0 on success.

If you do it this way, I can think of no reason your compiler or binary would just print "pppppp" like that. If it continues doing that, there is something wrong with your compiler or work space.

Tanner Babcock
  • 3,232
  • 6
  • 21
  • 23
  • 1
    error message should be output to `stderr`, not `stdout` and when the error is from a system function, should use: `perror()`; so both the enclosed text and the text related to the reason the system thinks the error occurred are output to `stderr`. – user3629249 Dec 24 '17 at 03:48
0

the following proposed code:

  1. cleans up after itself, in the current scenario by calling fclose() on the open file
  2. properly checks for errors when calling: fopen() and fscanf()
  3. properly uses the returned value from fscanf() for loop control
  4. documents why each header file is included
  5. ends the printf() format string with '\n' so the data is immediately passed to the terminal, rather than waiting for the program to exit.

And now the proposed code:

#include <stdio.h>   // fopen(), fclose(), fscanf(), perror(), printf()
#include <stdlib.h>  // exit(), EXIT_FAILURE


int main( void )
{
    FILE *fptr = fopen("input.txt","r");
    if( ! fptr )
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    int data;
    int count=0;

    while( 1 == fscanf(fptr,"%d",&data) )
    {
        count++;
    }

    printf("%d\n",count);

    fclose( fptr );
}
user3629249
  • 16,402
  • 1
  • 16
  • 17