Saifur Rahman Mohsin
Saifur Rahman Mohsin

Reputation: 1011

How to get file pointer value without moving to next file pointer location (in C)

Is there a way to find the character stored in file pointer without fgetc. Say I have a word "steve jobs" in a file called apple.txt is there something like

int main(int argc,char *argv[])
  {
   FILE *fp=fopen("apple.txt","r");
   if(fp=='s'&&(fp+2)=='e')
     printf("steve is there");
   else
     printf("Steve not there");
   fclose(fp);
  }

Clearly this doesn't really work! It just prints something like C forbids comparison b/n pointer n int. Even i tried adding * in front of (fp+2) and fp, it said no match for operator==

I believe the function fgetc(FILE *) works in such a way that it gets the unsigned char and then moves the pointer to the next location. Is there any function to just get the character without moving the pointer and also is the above code possible in any other way?!

Upvotes: 0

Views: 4929

Answers (2)

You might use getc and ungetc. Read the documentation about it (you can only have one push-back character).

On some systems (notably Posix systems like Linux) you have the ability to map into memory a portion of a file. Read more about the mmap system call which enables you to see a portion of a file as segment of memory. (mmap is not usable on non-seekable files like pipes or sockets; it basically works mostly on "disk" files).

Upvotes: 4

zwol
zwol

Reputation: 140540

"The character stored in file pointer" is not a meaningful thing to ask for. There aren't necessarily any characters stored in a FILE. For instance, stdin and stdout are often communication channels rather than files on the disk, and they may not be doing any buffering at all.

What you can do instead, if you know a FILE refers to an actual file on the disk rather than a communications channel, is read a few characters and then use fseek to move back to where you were before you read them. Your example program, rewritten to do that, would look something like this:

int main(void)
{
    FILE *fp = fopen("orange.txt", "r")
    if (!fp)
    {
        perror("fopen(orange.txt)");
        return 1;
    }

    if (getc(fp) == 'b' &&
        getc(fp) == 'a' &&
        getc(fp) == 'n' &&
        getc(fp) == 'a' &&
        getc(fp) == 'n' &&
        getc(fp) == 'a')
        puts("orange has a banana");
    else
        puts("orange has no bananas");

    /* return to the beginning of the file */
    if (fseek(fp, 0, SEEK_SET))
    {
        perror("fseek(orange.txt)");
        return 1;
    }

    /* do something else with `fp` here */

    /* all files are automatically closed on exit */
    return 0;
}

If you're working with a file whose nature you don't know, though -- such as any file given to you by the user -- you have to be prepared for fseek to fail and set errno to ESPIPE, which means "that's not a file, that's a data stream, you can't jump around in it".

Upvotes: 4

Related Questions