What can I use for input conversion instead of scanf?
c, scanf
Solution
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 single `char`.
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 using `scanf`, 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 or `strtok`, which is not thread-safe. You could also roll your own thread-safe variant using `strcspn` and `strspn`, as `strtok_r` doesn't involve any special OS support.
It may be overkill, but you can use lexers and parsers (`flex` and `bison` 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 to `scanf`'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.
Problem
I have very frequently seen people discouraging others from using `scanf` and saying that there are better alternatives. However, all I end up seeing is either "don't use `scanf`" or "here's a correct format string", and never any examples of the "better alternatives" mentioned. For example, let's take this snippet of code: ``` scanf("%c", &c); ``` This reads the whitespace that was left in the input stream after the last conversion. The usual suggested solution to this is to use: ``` scanf(" %c", &c); ``` or to not use `scanf`. Since `scanf` is bad, what are some ANSI C options for converting input formats that `scanf` can usually handle (such as integers, floating-point numbers, and strings) without using `scanf`?
Related problems
- How can I read an input string of unknown length?
- Why is the gets function so dangerous that it should not be used?
- Undefined, unspecified and implementation-defined behavior
- Removing trailing newline character from fgets() input
- scanf() leaves the newline character in the buffer
- Why should strtok(line, "\n") **not** be used to strip the newline left by fgets()