The most common ways of reading input are:
-
using
fgets
with a fixed size, which is what is usually suggested, and -
using
fgetc
, which may be useful if you’re only reading a singlechar
.
To convert the input, there are a variety of functions that you can use:
-
strtoll
, to convert a string into an integer -
strtof
/d
/ld
, to convert a string into a floating-point number -
sscanf
, which is not as bad as simply usingscanf
, although it does have most of the downfalls mentioned below -
There are no good ways to parse a delimiter-separated input in plain ANSI C. Either use
strtok_r
from POSIX orstrtok
, which is not thread-safe. You could also roll your own thread-safe variant usingstrcspn
andstrspn
, asstrtok_r
doesn’t involve any special OS support. -
It may be overkill, but you can use lexers and parsers (
flex
andbison
being the most common examples). -
No conversion, simply just use the string
Since I didn’t go into exactly why scanf
is bad in my question, I’ll elaborate:
-
With the conversion specifiers
%[...]
and%c
,scanf
does not eat up whitespace. This is apparently not widely known, as evidenced by the many duplicates of this question. -
There is some confusion about when to use the unary
&
operator when referring toscanf
‘s arguments (specifically with strings). -
It’s very easy to ignore the return value from
scanf
. This could easily cause undefined behavior from reading an uninitialized variable. -
It’s very easy to forget to prevent buffer overflow in
scanf
.scanf("%s", str)
is just as bad as, if not worse than,gets
. -
You cannot detect overflow when converting integers with
scanf
. In fact, overflow causes undefined behavior in these functions.