The most common ways of reading input are:
-
using
fgetswith 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_rfrom POSIX orstrtok, which is not thread-safe. You could also roll your own thread-safe variant usingstrcspnandstrspn, asstrtok_rdoesn’t involve any special OS support. -
It may be overkill, but you can use lexers and parsers (
flexandbisonbeing 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,scanfdoes 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.