Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getc() vs fgetc() - What are the major differences?

Tags:

c

getc

fgetc

Everywhere I see "it is practically identical", or something similar...

From The GNU C Programming Tutorial :

There is another function in the GNU C Library called fgetc. It is identical to getc in most respects, except that getc is usually implemented as a macro function and is highly optimised, so is preferable in most situations. (In situations where you are reading from standard input, getc is about as fast as fgetc, since humans type slowly compared to how fast computers can read their input, but when you are reading from a stream that is not interactively produced by a human, fgetc is probably better.)

What are the other differences? I have heard that they each have a different implementation (and one can be used as a macro) but, what makes them soo different (or different enough) for them to be both in the Standard C library (or specification)?

like image 240
Joe DF Avatar asked Aug 28 '13 06:08

Joe DF


People also ask

What is difference between fgetc and getc?

The difference between getc and fgetc is that getc can be implemented as a macro, whereas fgetc cannot be implemented as a macro. This means three things: The argument to getc should not be an expression with side effects. Since fgetc is guaranteed to be a function, we can take its address.

Is getc a macro?

getc is a macro, defined in stdio. h. You can use getc to get the next single character from the file or stream identified by fp. As a side effect, getc advances the file's current position indicator.

Is fgets faster than fgetc?

Each time you read (either via fgetc or fgets) you are making a system call which takes time, you want to minimize the number of times that happens, so calling fgets fewer times and iterating in memory is faster.


2 Answers

From the Advanced Programming in Unix Environment:

...

The difference between getc and fgetc is that getc can be implemented as a macro, whereas fgetc cannot be implemented as a macro. This means three things:

  • The argument to getc should not be an expression with side effects.
  • Since fgetc is guaranteed to be a function, we can take its address. This allows us to pass the address of fgetc as an argument to another function.
  • Calls to fgetc probably take longer than calls to getc, as it usually takes more time to call a function.

...

like image 153
mohit Avatar answered Sep 17 '22 17:09

mohit


Seems like the differences are, in 99.9% of the cases, meaningless.

One point which may make a difference - The man page says getc() may be implemented as a macro which evaluates stream more than once.

It could lead to strange behavior in some (not very useful) cases, e.g.:

FILE *my_files[10] = {...}, *f=&my_files[0]; for (i=0; i<10; i++) {     int c = getc(f++);    // Parameter to getc has side effects! } 

If getc evaluates f++ more than once, it will advance f more than once per iteration. In comparison, fgetc is safe in such situations.

like image 40
ugoren Avatar answered Sep 18 '22 17:09

ugoren