gpt4 book ai didi

c - 不理解 scanf 中的 Scanset 组合

转载 作者:太空宇宙 更新时间:2023-11-04 00:56:43 24 4
gpt4 key购买 nike

我不明白这个扫描集是如何工作的

scanf("%*[^:]%*2c%[^\n]", str1);// 1st scanf

完整代码是

int main()
{
int ch;
char str1[100];
printf("Enter input\n");
scanf("%*[^:]%*2c%[^\n]", str1);
printf("input is: %s",str1);
return 0;
}

如果输入是`

Any combination: You are free to use any combination.

输出是

input is: You are free to use any combination.

当我从 scanf 中删除 %*[^:]

现在 scanf 是 scanf("%*2c%[^\n]", str1);//第二次扫描

具有相同的输入

Any combination: You are free to use any combination.

输出是

input is: y combination: You are free to use any combination.

所以如果我从第一个 scanf 中删除 %*2c

现在 scanf 是 scanf("%*[^:]%[^\n]", str1);\\第三次扫描

输入是

Any combination: You are free to use any combination.

输出是

input is: : You are free to use any combination.

Agian 如果我从第一个 scanf 中删除 %[^\n]

现在 scanf 是 scanf("%*[^:]%*2c", str1);\\第四次扫描

输入是

Any combination: You are free to use any combination.

输出是

garbage value.

问题是每个 scanf 中的 scanset 如何工作?请逐步解释。

最佳答案

查看 https://en.cppreference.com/w/c/io/fscanf 上的 scanf 文档:

conversion specifications. Each conversion specification has the following format:

  • introductory % character

  • (optional) assignment-suppressing character *. If this option is present, the function does not assign the result of the conversion to any receiving argument.

  • (optional) integer number (greater than zero) that specifies maximum field width, that is, the maximum number of characters that the function is allowed to consume when doing the conversion specified by the current conversion specification.

...

[set]

  • matches a non-empty sequence of character from set of characters. If the first character of the set is ^, then all characters not in the set are matched...

所以分解你的格式字符串:

%*[^:] - 将所有内容匹配到 :,但不要分配给变量。基本上忽略冒号前的所有内容。

%*2c - 匹配 2 个字符但同样不分配它们。所以跳过冒号和后面的字符。

%[^\n] - 匹配直到 \n(新行字符)的所有内容,这将分配给 str1。因此,第一个冒号和后续字符之后的所有内容都会在此处进行匹配和分配。

因此对于输入Any combination: You are free to use any combination.,忽略的部分是Any combination:,结果在str1您可以自由使用任何组合。

补充说明

scanf("%*[^:]%*2c", str1) 导致打印垃圾的原因是因为两个格式说明符都没有分配 str1使其未初始化。恰好在 str1 数组的内存中的字节值被打印出来,因此是无稽之谈。在这种情况下,scanf(或 printf)样式函数有未使用的参数,大多数现代编译器都应发出警告。因此,请确保您已打开警告,并尝试解释和修复它们。

如果输入不包含 :,您的完整格式字符串也会发生同样的事情,在这种情况下,scanf 永远不会到达分配 的部分>str1 并且您的结果将再次成为垃圾。要解决这个问题,您需要查看 scanf 的返回值:

Return value

Number of receiving arguments successfully assigned (which may be zero in case a matching failure occurred before the first receiving argument was assigned), or EOF if input failure occurs before the first receiving argument was assigned.

在这种情况下,您将得到 EOF,因为输入将在分配 str1 之前结束。为确保 str1 有效,您需要检查返回值是否为 1

最后,正如评论中提到的,这里还有一个问题,如果用户在跳过的部分之后输入大于 str1 数组可以容纳的部分。请注意,scanf 会自动在字符串的末尾添加终止符 \0,因此输入的指定部分的最大长度为 99 个字符。如果输入较大,它将离开缓冲区的末尾并覆盖它不应该覆盖的内存。这很可能会导致程序行为异常或崩溃。通过向转换说明符添加最大字段宽度说明符,可以使格式字符串安全。简而言之,将 %[^\n] 更改为 %99[^\n]

关于c - 不理解 scanf 中的 Scanset 组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58258602/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com