该*scanf()
函数族返回成功匹配和分配的“输入项”(即转换规范)的数量:
返回值
如果成功,这些函数将返回成功匹配和分配的输入项的数量;如果早期匹配失败,这个数字可能会少于提供的数值,甚至为零。
现在,考虑一个格式字符串,该字符串包含一些转换规范,其中与一些文字字符交错,并以一个或多个文字字符结尾:
// read the response to a CSI 14 t request
int r = sscanf(input, "\033[4;%d;%dt", &resp_y, &resp_x);
考虑此 sscanf 调用的四个潜在输入:
"\033[4;100;200t"
"\033[4;100;200"
"\033[4;100;200foobar"
"\033[4;100;200tfoobar"
据我所知,在这种情况下,返回值(r
)在这三种情况下都将设置为2
。但是,只有输入(1)有效,而输入(2)和(3)无效,输入(4)包含尾随数据。
区分(1)与(2)和(3)以及(4)的最干净/最正确的方法是什么,即确保整个格式字符串与整个输入成功匹配?
sscanf()
我对和这个问题的答案都很感兴趣fscanf()
。
使用:
请注意,分配不算
n
作“转换”,因此不计入返回值中。如果您想确保使用了整个字符串
sscanf()
,那么您可以检查:这种使用技术
%n
可以与任何scanf()
函数系列一起使用。虽然我链接到了 POSIX 文档,但 C 标准也说了同样的事情。如果您正在从文件(fscanf()
或scanf()
而不是sscanf()
)读取,您可能不想检查n
第一个代码片段中显示的更多值。如果您想测试换行符(或其他空格),您不能如此轻松地使用scanf()
- 请参阅格式字符串中尾随空格的影响是什么scanf()
?。类似于@Jonathan Leffler 的好答案。
用于
" %n"
记录扫描的偏移。不仅要使用
"%n"
,还要考虑" %n"
首先消耗 0 个或更多空格。这很有用,因为input
通常有一个潜在的尾随'\n'
(可能来自fgets()
),并且格式消除了删除尾随空格(如)" "
的需要。这允许保存的扫描偏移量为行尾。input
'\n'
代码还可以检查
r == 2
皮带和吊带,但这不是必需的,因为n
只有当才会非零r == 2
。注意:匹配
"%n"
不会影响返回值。为了确定所有都已
input
使用,还要测试 是否input[n]
为空字符。区分此类输入的最干净/最正确的方法是避免
scanf
使用函数系列。相反,编写自己的解析器来实现您需要的所有检查。