1) getchar_unlocked() is much faster than getchar(), and putchar_unlocked() is slightly faster than putchar() (at least, this is how I remember it). This is merely because, in POSIX, getchar() is thread-safe, meaning it must lock the I/O stream (which takes time) whereas getchar_unlocked() does not lock, so that it is not thread-safe but works perfectly fine in single-threaded programs (like the ones submitted to SPOJ). The technique of using getchar_unlocked() to read integers one digit at a time is easy to code and very efficient.
2) For squeezing out those hundredths of a second in an attempt to beat your ranklist competitors, you might want to consider fread() and fwrite() instead. But note that the unlocked variants of fread() and fwrite() are only slightly faster than fread() and fwrite() themselves. This is because the locking and unlocking, a costly operation in terms of time, occurs only once every time an I/O function is called. So the time to perform one million getchar()s is one million locks and one million unlocks slower than the time to perform one million getchar_unlocked()s, but the time to perform one fread() (that reads in a million bytes at once) is only one lock and one unlock slower than the time to perform one fread_unlocked().
3) gets() is very fast. It should never, ever be used in software design, but it is useful in solving string problems. If most of the input consists of string data, then manual buffering with fread() is not worth the effort to implement, because gets() will be very nearly as fast. On the other hand, manual buffering with fread() is very useful when the input consists of millions of integers.
4) Take advantage of the generous 256 MB memory limit on SPOJ. If you can store the entire input and output in memory, do so. Read in the entire input file at once at the beginning, and dump the entire output file out at the end. Request that fread() read an unreasonably high number of bytes (you presumably don't know how much input there really is) because it stops once it hits the end-of-file anyway.
5) Don't be tempted to use read() just because it's more "low-level" than fread(). Adrian Kosowski told me that programs tested on SPOJ read from pipes, and on Linux the pipe buffer size is 64K, so I think that if you attempt to read 1 MB of data using read(), it'll just give you the first 64K and then return. You can get read() working by busy-waiting on stdin, but it's not worth it (I've tried it myself).