为什么在[0-9A-Z ^%]之后不应该有像s或c这样的类型说明符?

时间:2018-03-04 13:39:51

标签: c file scanf

例如,请考虑以下代码 -

fscanf(fp,"%d:%d:%[^:]:%[^\n]\n",&pow->no,&pow->seen,pow->word,pow->means);     
printf("\ntthis is what i read--\n%d:%d:%s:%s:\n",pow->no,pow->seen,pow->word,pow->means);

这里pow是指向之前声明的对象的指针,

当我将s放在fscanf(fp,"%d:%d:%[^:]s:%[^\n]\n"中时,第3个被读取但不是最后一个

输出是 - 4:0:Abridge::

但当我fscanf(fp,"%d:%d:%[^:]:%[^\n]s\n"时,所有人都会被阅读 输出是 - 4:0:Abridge:To condense:

并且没有任何地方fscanf(fp,"%d:%d:%[^:]:%[^\n]\n"都被读取 输出是 - `4:0:Abridge:凝聚:

WHY ??

2 个答案:

答案 0 :(得分:2)

说明符 IS "%[]",您不需要"s"

阅读manual page for scanf()

您的格式字符串与输入不匹配,因为"s"不是说明符的一部分,而且格式所期望的输入中不存在它。

通过阅读上面链接中的文档,您会发现 - 如果您还不知道 - 您还应该在致电scanf()之前检查printf()的返回值,否则你的代码会调用未定义的行为,因为一些传递的指针不会被初始化。

答案 1 :(得分:1)

要回答您的问题%[^\n]s的含义是什么,有两种格式说明符,一种是[],另一种是s

现在第一个将扫描除\n以外的任何内容,然后获取\n并将其保留在stdin中。继续前进。但它并没有停在这里 - 它基本上试图找到一个匹配的字母s。如果它找不到它 - 它失败了。 (%[^:]s的解释与此相同。)

现在决定这是否是你真正想要的。[^\n]是正确的,它将扫描直到\n被找到(是的,它不会跳过像%s那样的空格) 。 scanset也涵盖了包括s在内的字母。而%[^\n]s更多的是自相矛盾的。所以也没有使用它。

%d:%d:%[^:]s:%[^\n]


%d - Matches an optionally signed decimal integer. (Ignore whitespace)
:  - Then looks for ':'
%d - Matches an optionally signed decimal integer. (Ignore whitespace)
:  - Then looks for ':'
%[^:] - No white space ignored - everything is taken into input except `:`
     ':' is unread.
s  - Tries to match 's'. No white space ignored.
%[^\n] - Everything except '\n' inputted. `\n` left unread.