fscanf中的分配抑制标志
请查看此代码段:fscanf中的分配抑制标志,c,scanf,C,Scanf,请查看此代码段: char line[80]; if(fscanf(stdin, "%*[\t\v\f ]%79[^\n]", line) != EOF) printf("%s\n", line); 输出: $ gcc line.c -o line $ ./line One space at the beginning. One space at the beginning. $ ./line No space at the beginning. $ 现在如果开头没有空格
char line[80];
if(fscanf(stdin, "%*[\t\v\f ]%79[^\n]", line) != EOF)
printf("%s\n", line);
输出:
$ gcc line.c -o line
$ ./line
One space at the beginning.
One space at the beginning.
$ ./line
No space at the beginning.
$
现在如果开头没有空格
为什么整个字符串没有按原样打印
$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3
如果行首没有空格、制表符或分页符,
scanf
将在第一次匹配时失败。一旦失败,它就不会尝试匹配模式的其余部分
此外,不需要手动匹配这些字符,格式字符串中的一个空格将扩展为输入字符串中任意数量的空格。请参阅的文档以检查哪些字符被视为空白。它失败,因为%*[\t\v\f]“不匹配,因此后续的格式说明符
%79[^\n]
未被处理且行
未分配。要跳过前导空格,请将扫描集替换为前导空格:
if(fscanf(stdin, " %79[^\n]", line) == 1)
printf("%s\n", line);
如果找不到字段,您的扫描将很难退出@hmjd 注意:使用
fgets()
是一种更好的方法,但要坚持OP风格:
// consume select leading whitespaces, if any, but not \n
fscanf(stdin, "%*[\t\v\f ]");
// Scan non-eol chars
char line[80];
if (fscanf(stdin, "%79[^\n]", line) == 1) {
printf("%s\n", line);
}
// scan a single EOL
char eol[2];
if (fscanf(stdin, "%1[\n]", eol) == 1) {
; // EOL found
}
通过分成3个
fscanf()
调用,每种格式都会依次尝试,即使之前的一个失败。对此表示抱歉,意外地编辑了您的答案而不是我自己的。fscanf
在开头一个空格的情况下也会失败,尽管不是在第一个字符。并且不能在此处使用空格,因为它将使用驻留在每行末尾的\n
字符,如果有空行,则会产生问题。i、 e.仅包含\n
的行。@rootkea,我不确定你说的不在第一个字符是什么意思?对不起,我的意思是[\t\v\f]
在开头有一个空格的情况下失败,尽管不是在第一个字符。@rootkea,目标是跳过每行的任何前导空格吗?@rootkea,使用fgets()
读取一行。使用sscanf()
从中提取。