根据sscanf()的手册页,*字符
可选的'*'赋值抑制字符:scanf()读取输入 按照转换规范的指示,但丢弃输入。
由此,我(正确地?)假设像
这样的东西[eggs, lasers, hats, pie]
eggs
lasers
hats
pie
eggs
pie
将输入“text | neededtext |”,忽略第一个“|”之前的所有文本(即从stdin中删除它?),忽略(并从stdin中删除)下一个字符,即“|”存储“requiredtext”然后删除最后的“|”性格,让stdin空着? 如果是,那么在sscanf()调用之后是否需要运行清理函数,以便在出现问题时捕获一些奇怪的异常,或者上面的代码是否始终保证有效?
我已经运行了一些测试,似乎sscanf()确实吃掉了stdin中的所有字符,但我只想确定。
答案 0 :(得分:0)
并非总是如此。见#2
@Jonathan Leffler评论,sscanf()
使用字符串,不会影响stdin
。让我们假设问题是关于*scanf()
家庭。
*scanf(string,"%*[^|]%*c%[^|]%*c", vars)
代码不会检查*scanf()
的结果。这导致微妙的检测问题。最好为支票编码。
char vars[100];
if (sscanf(string,"%*[^|]%*c%99[^|]%*c", vars) != 1) Handle_Error();
"%*[^|]"
,则 '|'
不扫描任何内容并停止整个扫描功能。 "%*[^|]"
扫描1个或多个非'|'
,而不是0或更多。因此,"并非总是"以上。使用scanf()
时,不会消耗任何字符 - 它们会保留在stdin
。
"%*[^|]"
继续扫描后唯一可能的字符为'|'
。代码"%*[^|]%|"
可能比"%*[^|]%*c"
sscanf()
与scanf()
和fscanf()
的不同之处在于后两者可以扫描并保存空字符'\0'
。 sscanf()
在到达空字符时停止扫描。 IMO:应避免使用"%s"
和"%[^...]
与fscanf() scanf()
以防止黑客利用。 OP' fgets()+sscanf()
是更好的方法。
%[^|]
缺少宽度。如果没有此限制,则不会阻止缓冲区溢出。见#1。
"%*c"
可能会扫描或不扫描角色。结果值不反映其成功或失败,因为'*'
的扫描指令不直接对返回值有贡献。如果需要"%*c"
成功跟踪扫描(每个点#3可能"|"
),建议使用"%n"
检测是否正在进行扫描。
char vars[100];
int n = 0;
sscanf(string,"%*[^|]|%99[^|]| %n", vars);
if (n > 0) Success();
// May also want to use
if (string[n]) Fail_ExtraTextOnLine();
在C中,%*[^|]
是scanf
说明符,而不是分隔符。