我可以用什么代替scanf进行输入转换? [英] What can I use for input conversion instead of scanf?
问题描述
我经常看到人们不鼓励其他人使用 scanf
,并说有更好的选择.但是,我最终看到的只是不要使用 scanf
" 或这是正确的格式字符串" ,从没有任何示例提到的更好的选择" .
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);
或不使用 scanf
.
由于 scanf
不好,因此有哪些ANSI C选项可以转换 scanf
通常可以处理的输入格式(例如整数,浮点数和字符串)不使用 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
?
推荐答案
读取输入的最常见方式是:
The most common ways of reading input are:
-
使用具有固定大小的
fgets
(通常建议这样做),并且
using
fgets
with a fixed size, which is what is usually suggested, and
使用 fgetc
,如果您只读取单个 char
,这可能会很有用.
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
,将字符串转换为整数
strtof
/ d
/ ld
,以将字符串转换为浮点数
strtof
/d
/ld
, to convert a string into a floating-point number
sscanf
,虽然使用了以下大多数错误,但并不像使用 scanf
那样糟糕.
sscanf
, which is not as bad as simply using scanf
, although it does have most of the downfalls mentioned below
在普通的ANSI C中没有很好的方法来解析以分隔符分隔的输入.要么使用POSIX中的 strtok_r
,要么使用非线程的strtok .安全的.您还可以自行滚动使用 strcspn
和 strspn
的线程安全变体,因为 strtok_r
不涉及任何特殊的操作系统支持.
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.
这可能有些矫kill过正,但是您可以使用词法分析器和解析器(最常见的示例是 flex
和 bison
).
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
由于我没有完全了解为什么 scanf
在我的问题中不好,所以我将详细说明:
Since I didn't go into exactly why scanf
is bad in my question, I'll elaborate:
-
使用转换说明符
%[...]
和%c
,scanf
不会占用空格.这显然未被广泛了解,例如这个问题.
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.
在引用 scanf
的参数(特别是字符串)时,何时使用一元&
运算符存在一些困惑.
There is some confusion about when to use the unary &
operator when referring to scanf
's arguments (specifically with strings).
很容易忽略 scanf
的返回值.读取未初始化的变量很容易导致未定义的行为.
It's very easy to ignore the return value from scanf
. This could easily cause undefined behavior from reading an uninitialized variable.
很容易忘记防止 scanf
中的缓冲区溢出. scanf(%s",str)
和 gets
一样糟糕,甚至更糟.
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
.
使用 scanf
转换整数时,您无法检测到溢出.实际上,溢出会导致不确定的行为在这些功能中.
You cannot detect overflow when converting integers with scanf
. In fact, overflow causes undefined behavior in these functions.
这篇关于我可以用什么代替scanf进行输入转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!