fscanf中的赋值抑制标志

时间:2013-05-27 14:04:30

标签: 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.

$

现在如果No space at the beginning为什么整个字符串不会按原样打印?

$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3

3 个答案:

答案 0 :(得分:2)

它失败,因为"%*[\t\v\f ]"没有匹配,因此未处理后续格式说明符%79[^\n]并且未分配line。要跳过前导空格,请使用前导空格替换扫描集:

if(fscanf(stdin, " %79[^\n]", line) == 1)
    printf("%s\n", line);

答案 1 :(得分:0)

如果在行的开头没有空格,制表符或分页符,则

scanf将在第一个匹配%*[\t\v\f ]上失败。一旦失败,它将不会尝试匹配模式的其余部分。

此外,您不需要手动匹配这些字符,格式字符串中的一个空格将扩展为输入字符串中的任意数量的空格。请参阅isspace的文档以检查哪些字符被视为空格。

答案 2 :(得分:0)

如果找不到某个字段,并且@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()次调用,即使先前的格式失败,也会尝试使用每种格式。