What can I use for input conversion instead of scanf?

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.

Leave a Comment