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

Ali*_*nık 5 c input scanf

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

%[^\n]- 当我运行这个时,scanf按回车键后正在输入和终止。(可能留\n在输入系统中)

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

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

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

    printf("%s", s);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明

最后一个:

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

这三个是如何工作的,它们有什么不同?

chu*_*ica 4

所有 3 种格式均以"%[^\n]".

"%[^\n]"糟糕的代码2缺乏宽度限制,并且容易受到缓冲区溢出的影响。使用宽度限制,"%99[^\n]"char s[100];.

"%[...]"不像许多其他说明符那样消耗前导空格。

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

如果没有读取任何字符(不计算'\n'),则说明符失败并scanf()返回而不更改s- 不使用格式的其余部分。没有附加空字符

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


"\n"" "其作用与、 、 相同"\t""any_white_space_chracter"读取并丢弃 0 个或多个空白字符。它会继续这样做,直到读取到非空白1 。该非空白字符被放回到stdin.

给定行缓冲输入,这意味着需要在输入后面包含非空格的才能看到下一个非空格并允许scanf()继续前进。

格式末尾的 , a 是不好scanf()会导致 OP 的问题。"\n"


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


更好的选择是使用fgets().

char s[100];
if (fgets(s, sizeof s, stdin)) {
   s[strcspn(s, "\n")] = '\0';  // To lop off potential trailing \n
Run Code Online (Sandbox Code Playgroud)

一个较小的选择是

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.
Run Code Online (Sandbox Code Playgroud)

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

2 IMO,比 更糟糕gets()