0


I'm having some problems with this little function that can read a file:

void ReadFile(char *name) {
FILE *fr;
int lenght, i;
fr = fopen(name, "r");  //Open the file reader
fseek(fr, 0, 2);        //Set the pointer at the EOF
lenght = ftell(fr);     //Read the ending position
printf("\nDEBUG lenght:%d\n", lenght);
fseek(fr, 0, 0);        //Return at the beginning of the file

printf("File read:\n\n");
for (i = 1; i <= lenght; i++) {
    printf("%c", getc(fr));
    fseek(fr, i, 0);
}
fclose(fr);
}

This is the file that it reads:

qwerty

asdfgh
zxcvbn

But this is the output of the program:

DEBUG lenght:24
File read:

qwerty



asdfgh

zxcvbn

It is basically reading an extra "\n" when there is one before.
Any ideas of why the code doesn't work?

Thanks

LeonardoA
  • 3
  • 1
  • 2
  • why is that fseek there? the one in the read loop – pm100 Apr 16 '18 at 20:06
  • platform? windows? – pm100 Apr 16 '18 at 20:08
  • 1
    you are messing up the reading by doing the extra `fseek(fr, i, 0);` in the for loop. Remove that and it will print what you expect. – Pablo Apr 16 '18 at 20:23
  • Thanks, I thought I had to move the cursor "manually" – LeonardoA Apr 16 '18 at 20:59
  • please post a [mcve] so we can easily reproduce the problem. – user3629249 Apr 17 '18 at 04:37
  • for ease of readability and understanding: 1) please indent the code consistently. Indent after every opening brace '['. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) follow the axiom: *only one statement per line and (at most) one variable declaration per statement.* – user3629249 Apr 17 '18 at 05:06
  • Most C library functions return a value, That value can indicate success or failure. Strongly suggest checking the returned value from `fopen()` `fseek()` `ftell()` – user3629249 Apr 17 '18 at 05:07

2 Answers2

2

If you open a file in text mode (as you do), then a call to fseek may only contain offset values that have been previously retrieved by an ftell function (cf, for example, cppreference/fseek):

If the stream is open in text mode, the only supported values for offset are zero (which works with any origin) and a value returned by an earlier call to ftell on a stream associated with the same file (which only works with origin of SEEK_SET).

In your for-loop, however, you are passing the value of i, which is not retrieved by ftell.

Besides that, your fseek in the loop is superflous, as fgetc moves the read pointer forward anyway. So for (i = 1; i <= lenght; i++) { printf("%c", getc(fr)); } should do the job.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • Thanks a lot! I tought that I had to move the cursor manually with getc. Thanks for the information on the offset value of fseek, I didn't knew that too – LeonardoA Apr 16 '18 at 21:04
0

the following proposed code:

  1. cleanly compiles
  2. performs the desired functionality
  3. properly checks for errors

and now, the proposed code:

#include <stdio.h>   // EOF, fopen(), getc(), putc() fclose() puts() perror()
#include <stdlib.h>  // exit(), EXIT_FAILURE

// prototype
void ReadFile(char *filename);


void ReadFile(char *filename)
{
    FILE *fp = fopen( filename, "r" );

    if( !fp )
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    puts("File read:\n");

    int ch;
    while( (ch = getc( fp )) != EOF )
    {
        putchar( ch );
    }

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