c - 我可以使用什么来进行输入转换而不是 scanf?
问题描述
我经常看到有人劝阻他人使用scanf
并说有更好的选择。但是,我最终看到的只是“不要使用scanf
”或“这是一个正确的格式字符串” ,而从来没有提到任何“更好的选择”的例子。
例如,让我们看一下这段代码:
scanf("%c", &c);
这将读取上次转换后留在输入流中的空白。通常建议的解决方案是使用:
scanf(" %c", &c);
或不使用scanf
.
既然scanf
不好,那么有哪些 ANSI C 选项可以转换scanf
通常可以在不使用的情况下处理的输入格式(例如整数、浮点数和字符串)scanf
?
解决方案
最常见的读取输入的方法是:
使用
fgets
固定大小,这是通常建议的,并且using
fgetc
,如果您只阅读单个char
.
要转换输入,您可以使用多种函数:
strtoll
, 将字符串转换为整数strtof
//d
,ld
将字符串转换为浮点数sscanf
,这并不像简单地使用那么糟糕scanf
,尽管它确实有下面提到的大部分缺点没有很好的方法来解析纯 ANSI C 中分隔符分隔的输入。要么使用
strtok_r
POSIX 或strtok
,这不是线程安全的。您还可以使用and滚动您自己的线程安全变体,因为它不涉及任何特殊的操作系统支持。strcspn
strspn
strtok_r
这可能有点矫枉过正,但您可以使用词法分析器和解析器(
flex
并且bison
是最常见的示例)。无需转换,只需使用字符串
由于我没有详细说明为什么 scanf
我的问题不好,我将详细说明:
使用转换说明符
%[...]
and%c
,scanf
不会占用空格。正如这个问题的许多重复所证明的那样,这显然并不广为人知。&
在引用scanf
的参数(特别是字符串)时,何时使用一元运算符存在一些混淆。很容易忽略
scanf
. 这很容易导致读取未初始化变量的未定义行为。很容易忘记防止
scanf
.scanf("%s", str)
和 . 一样糟糕,如果不比gets
.使用 转换整数时无法检测到溢出
scanf
。事实上,溢出会导致这些函数出现未定义的行为。
推荐阅读
- cordova - 运行 ionic cordova build ios 时找不到包含的文件
- python - 线程数据共享
- delphi - Delphi IWinHTTPRequest SetRequestHeader
- python - 正则表达式在更多条件下匹配版权声明中的公司名称
- python - 我在使用形态掩码时遇到错误
- html - 将 div 垂直和水平居中
- c# - 编译服务此请求所需的资源期间发生错误。- DLL 错误
- eclipse - Eclipse IDE - 层次结构树中符号的含义
- python - 在没有某些字段的情况下查询 MongoDB 中的列表
- html - 使用滚动捕捉和位置粘性进行堆栈滚动