我正在查看一些代码并遇到了这一行:
fscanf(file, "%*[: ]%16s", dest);
格式字符串说明符有什么%*[: ]%16s
作用?
我正在查看一些代码并遇到了这一行:
fscanf(file, "%*[: ]%16s", dest);
格式字符串说明符有什么%*[: ]%16s
作用?
此格式字符串
"%*[: ]%16s"
表示必须在输入流中跳过所有符号':'
和' '
(放在格式字符串中方括号中的符号),然后在字符数组中最多读取 16 个字符。
在格式字符串中,符号*
是赋值抑制字符。
这是一个演示程序。为了可见性,我使用sscanf
而不是fscanf
.
#include <stdio.h>
int main( void )
{
const char *stream = "::: : : : :::Hello";
char s[17];
sscanf( stream, "%*[: ]%16s", s );
printf( "\"%s\"\n", s );
return 0;
}
程序输出为
"Hello"
它读取任何空格或:
(冒号)字符,然后丢弃它们,然后将最多 16 个非空白字符读入dest
(包括空终止符在内的 17 个\0
)。
*
之后是“%
赋值抑制字符”。%
和之间的数字s
是“最大字段宽度”。方括号表示匹配其中的字符或除这些字符之外的所有字符(带有插入符号)。破折号和插入符号经过特殊处理。
来自 scanf 的 Linux 手册页:
格式中的每个转换规范都以字符“%”或字符序列“%n$”开头(区别参见下文),后跟:
· 一个可选的'*' 赋值抑制字符: scanf() 按照转换规范的指示读取输入,但丢弃输入。不需要相应的指针参数,并且此规范不包括在 scanf() 返回的成功分配计数中。[剪辑]
· 一个可选的十进制整数,它指定最大字段宽度。当达到此最大值或找到不匹配的字符时,字符的读取将停止,以先发生者为准。大多数转换会丢弃初始空白字符(例外情况如下所述),并且这些丢弃的字符不计入最大字段宽度。字符串输入转换存储一个终止空字节('\0')来标记输入的结束;最大字段宽度不包括此终止符。
可以使用以下转换说明符:
[剪辑]
s 匹配一系列非空白字符;next 指针必须是指向字符数组的初始元素的指针,该元素的长度足以容纳输入序列和自动添加的终止空字节 ('\0')。输入字符串在空白处或最大字段宽度处停止,以先发生者为准。
[剪辑]
[ 匹配指定的可接受字符集中的非空字符序列;next 指针必须是指向 char 的指针,并且必须有足够的空间容纳字符串中的所有字符,外加一个终止空字节。前导空白的通常跳过被抑制。字符串由特定集合中(或不在)中的字符组成;该集合由左括号 [ 字符和右括号 ] 字符之间的字符定义。如果左括号后的第一个字符是抑扬符 (^),则该集合排除这些字符。要在集合中包含右括号,请将其作为左括号或抑扬符之后的第一个字符;任何其他位置将结束该组。连字符 - 也很特殊;当放置在其他两个角色之间时,它将所有中间字符添加到集合中。要包含连字符,请将其设为最后一个右括号之前的最后一个字符。例如,[^]0-9-] 表示集合“除了右括号、0 到 9 和连字符之外的所有内容”。字符串以出现不在(或,带有抑扬符,in)集中的字符或字段宽度用完时结束。
– scanf(3)的 Linux 手册页
格式字符串说明符有什么
"%*[: ]%16s"
作用?
"%*[: ]"
: 读取并丢弃(由于"*"
)scan_set的至少一个输入字符: , . 如果没有, 找到,停止扫描。':'
' '
':'
' '
"%16s"
有 3 个步骤:1)读取并丢弃任何(0 个或更多)前导空格。例如' '
, '\n'
, '\t'
, 等。 2) 读取并保存到dest
至少一个但不超过 16 个非空白 - 否则停止扫描。3) 将空字符附加到dest
. 因此dest
应至少为 17:char dest[16+1];
先进的
fscanf()
和的一个奇怪的区别sscanf()
是,当sscanf()
读取一个空字符时,扫描停止。随着fscanf()
,扫描继续。
与, , , , , , , ,的fscanf(file "%s", dest)
8 个字符文件数据将得到'\t'
, '1'
, '2'
, '3'
, , , , . 在文本文件中出现空字符是不常见的。'\0'
'x'
'y'
'z'
dest[]
'1'
'2'
'3'
'\0'
'x'
'y'
'z'
'\0'