`"%[^\n]"` 和 `"%[^\n]\n"` 和 `"%[^\n]%*c"` 在 C 中的区别 它们是如何工作的?

Difference between `"%[^\n]"` and `"%[^\n]\n"` and `"%[^\n]%*c"` in C how do they work?

我在其他地方找不到答案。

%[^\n] - 当我 运行 这个时,scanf 正在获取输入并在我按 enter 后终止。 (可能在输入系统中留下 \n

%[^\n]\n - 这个正在获取输入,但 scanf 并没有在我像上面那样按回车键后立即终止。我点击了更多的回车键,它产生了更多的换行符。当我输入一个字符然后按回车键时,它终于终止了。示例:

int main(void)
{
    char s[100];

    scanf("%[^\n]\n", s);

    printf("%s", s);

    return 0;
}

结果:

最后一个:

%[^\n]%*c - 当我输入一些内容并按回车键时。 scanf 立即终止。

这 3 个是如何工作的,它们有何不同?

所有 3 种格式都以 "%[^\n]" 开头。

"%[^\n]" 是糟糕的代码 2,缺少宽度限制并且容易发生缓冲区溢出。使用 width 限制,例如 "%99[^\n]"char s[100];

"%[...]" 像许多其他说明符一样消耗前导白色space。

此说明符指示读取输入,直到遇到 '\n'1'\n' 放回 stdin。所有其他字符都保存在匹配目标的数组 s.

如果没有读取任何字符(不包括 '\n'),说明符失败并且 scanf() returns without 改变 s - 其余格式未使用。没有附加 空字符

如果字符被读取,它们将被保存并在 s 后附加一个 空字符 并继续扫描格式的下一部分。


"\n" 的行为就像 " ""\t""any_white_space_chracter" 一样,会读取和抛出 0 个或更多的白色 space 字符。它继续这样做,直到读取到非白色-space1。那个非白色 space 字符被放回 stdin.

给定行缓冲输入,这意味着需要一个 和非白色 space 跟随输入才能看到下一个非白色 space 和让 scanf() 继续前进。

对于 scanf(),格式末尾的 "\n" 错误的 并导致了 OP 的问题。


"%*c" 读取 1 个字符 1 并将其丢弃 - 即使它不是 '\n'。由于 '*'.

,此说明符不计入 return 计数

更好的替代方法是使用 fgets()

char s[100];
if (fgets(s, sizeof s, stdin)) {
   s[strcspn(s, "\n")] = '[=10=]';  // To lop off potential trailing \n

一个较小的选择是

char s[100] = { 0 };
scanf("%99[^\n]", s);
// With a separate scanf ....
scanf("%*1[\n]");  // read the next character if it is a \n and toss it.

1 ... 或文件结束或罕见的输入错误。

2 IMO,比 gets().