`"%[^\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()
.
差
我在其他地方找不到答案。
%[^\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'
。由于 '*'
.
更好的替代方法是使用 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()
.