0

hello i wrote below a program in c,

#include <stdio.h>
#include <conio.h>

void main()
{
    FILE *fp;
    char c;
    long n=0L;
    fp=fopen("myfile.txt","w");
    printf("Enter the data into file:\n");
    while((c=getchar())!=EOF)
    {
        putc(c,fp);
    }
    printf("Total character into file:%ld\n",ftell(fp));
    fclose(fp);
    fp=fopen("myfile.txt","r");
    while(feof(fp)==0)
    {
        fseek(fp,n,0);
        printf("\n char:'%c' at position '%ld'",getc(fp),ftell(fp));
        n++;
    }
    fclose(fp);
    getch();
}

it work fine but when i replace the statement:

printf("\n char:'%c' at position '%ld'",getc(fp),ftell(fp));

with the statement:

printf("\n position '%ld'",ftell(fp));

then it will going to infinite loop
I knew the function,

fseek()
It set the file pointer to specified position. but here what happen,i don't understand. please help me.
William Pursell
  • 204,365
  • 48
  • 270
  • 300
Harish
  • 23
  • 6

5 Answers5

0

Reason for infinite loop : In your second case you do not progress the stream as in first case

getc()

Returns the character currently pointed by the internal file position indicator of the specified stream. The internal file position indicator is then advanced to the next character.

A solution :

#include <stdio.h>

void main()
{
    FILE *fp;
    char c;

    long n = 0L;
    fp=fopen("main.c","r");

    while(getc(fp)!=EOF)
    {
        fseek(fp,n,0);
        printf("\n position '%ld'",ftell(fp));
        n++ ;
    }
    fclose(fp);

}

Furthermore :

fseek() do not progress the file pointer.

Sets the position indicator associated with the stream to a new position.

feof()

This indicator is generally set by a previous operation on the stream that attempted to read at or past the end-of-file."

So this explains your failure. Second implementation does not come across EOF as first case. Provided sample of code would provide you an workaround.

Kavindu Dodanduwa
  • 12,193
  • 3
  • 33
  • 46
0

Check in documentation if fseek or ftell sets feof() result. Possibly not, so when you removed getc call feof can no longer return 'true', hence infinite loop.

Anyway, are you interested in the explanation why this program behaves strange or rather how you should write your program properly to achieve the result described...?

CiaPan
  • 9,381
  • 2
  • 21
  • 35
0

fseek() will not set the EOF marker, and in fact it can unset the EOF marker and it should do it after a succesful call.

Also, as the link points out the while (feof(fp) == 0) is always wrong, it's because you need to fgetc() one extra char for the EOF marker to be set, so you will have one extra iteration, instead you have to do it this way

#include <stdio.h>

int main()
{
    FILE    *fp;
    int      c; /* this should be 'int' and not 'char' */
    long int n;

    fp = fopen("myfile.txt", "w");
    if (fp == NULL)
        return -1;
    printf("Enter the data into file:\n");
    while ((c = getchar()) != EOF)
        putc(c, fp);
    printf("Total character into file:%ld\n", ftell(fp));
    fclose(fp);

    fp = fopen("myfile.txt","r");
    if (fp == NULL)
        return -1;
    while ((c = fgetc(fp)) != EOF)
    {
        if (c == '\n')
            printf("charcater `\\n' at position '%ld'\n", ftell(fp));
        else
            printf("charcater `%c' at position '%ld'\n", c, ftell(fp));
        n++;
    }
    fclose(fp);

    return 0;
}
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
0

A successful call fseek function clear the end-of-file indicator, but your loop condition rely on feof, so feof(fp) == 0 always true.

alijandro
  • 11,627
  • 2
  • 58
  • 74
0

fseek(SEEK_SET) merely sets the FILE's pointer to a position in the file. It doesn't actually do any reading of the file or anything. So, it will gladly let you set the position to WAY past the end of the file (and it clears any existing EOF set on the stream). ftell() merely returns the position of the file pointer.

Without doing a read of some sort (e.g. - getc()), EOF won't be set on the stream and your loop will be infinite.

You can do a fseek(fp, 0, SEEK_END) and then an ftell() to know the size / end of the file position.

PS - You really need to check your return values more carefully and handle any failures.

jschultz410
  • 2,849
  • 14
  • 22