So I'm little confused about which one to use when efficiency is considered.
None of them. I/O is slow. If you need efficiency, don't do I/O. Or, what's more likely is that you don't really need efficiency but you need I/O and you are optimizing prematurely.
Apart from that, here's the difference:
gets()
is dangerous and has been removed from the standard, don't use it.
scanf()
is standard, but it's clumsy and hard to use correctly. Apart from very specialized use cases, it's not worth bothering with it.
fgets()
is easier to use correctly and it is the preferred way of getting raw untrusted user input (i. e. user input in general). It can also read from any FILE *
stream, not only stdin
.