[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]
Re: getc() and fgetc()
Disillusioned forced the electrons to say:
> I could not understand the difference between getc() and fgetc(). Similarily
> the difference between putc() and fputc().
getc() and fgetc() are equivalent in usage. Similar for putc() and fputc().
> the text says that the former can be implemented as a macro, now what does
> that mean?
That is the essential difference. This means that stdio.h might implement
getc() as a macro, so taking its address is not portable. If you need a
pointer to a function that takes one argument of type FILE * and returns
an int (;-), then you cannot portably use getc(), you will have to use
fgetc() which is guaranteed to be a function.
So, this is not portable:
int (*func)(FILE *) = getc;
whereas this is:
int (*func)(FILE *) = fgetc;
[Note: This difference also comes in if you dlopen() libc and try to
locate getc() and fgetc() in there via dlsym()].
Another difference is that getc() might evaluate its argument multiple
times, so if you have an array of FILE * pointers, then code like this
to read one character from each of them is bad:
FILE **arr; /* array [10] of FILE * pointers */
int i = 0, c[10];
while (i < 10) {
c[i++] = getc(*arr++);
}
(Horrible, but you get the idea)
Whereas it is perfectly alright to use fgetc() in the above.
Here is an implementation of getc() (from /usr/lib/bcc/include/stdio.h) that
exhibits all the above points:
#define getc(stream) \
(((stream)->bufpos >= (stream)->bufread) ? fgetc(stream): \
(*(stream)->bufpos++))
This evaluates stream thrice.
Binand