不了解scanf中的Scanset组合

基利

我不明白此扫描集如何工作

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;
}

如果输入为

任意组合:您可以自由使用任何组合。

输出为

输入为:您可以自由使用任何组合。

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

现在scanf是 scanf("%*2c%[^\n]", str1); //2nd scanf

使用相同的输入

任意组合:您可以自由使用任何组合。

输出为

输入是:y组合:您可以自由使用任何组合。

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

现在scanf是 scanf("%*[^:]%[^\n]", str1); \\3rd scanf

输入为

任意组合:您可以自由使用任何组合。

输出为

输入为::您可以自由使用任何组合。

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

现在scanf是 scanf("%*[^:]%*2c", str1); \\4th scanf

输入为

任意组合:您可以自由使用任何组合。

输出为

垃圾值。

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

格莱美

scanfhttps://en.cppreference.com/w/c/io/fscanf查看文档

转换规格。每个转换规范具有以下格式:

  • 介绍性的%字符

  • (可选)禁止分配字符*。如果存在此选项,则该函数不会将转换结果分配给任何接收参数。

  • (可选)整数(大于零),它指定最大字段宽度,即在执行当前转换规范所指定的转换时允许该函数使用的最大字符数。

...

[组]

  • 匹配字符集中的非空字符序列。如果集合中的第一个字符是^,则匹配集合中所有不在的字符...

因此,请分解您的格式字符串:

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

%*2c-匹配2个字符,但同样不要分配它们。因此,在此之后跳过冒号和字符。

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

因此,使用input Any combination: You are free to use any combination.,忽略的部分为Any combination: ,而结果str1You are free to use any combination.

进一步说明

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

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

返回值

成功分配的接收参数的数量(如果在分配第一个接收参数之前发生匹配失败,则为零);如果在分配第一个接收参数之前发生输入失败,则为EOF。

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

不了解scanf的返回值

来自分类Dev

了解PHP中的特质与组合

来自分类Dev

了解PHP中的特质与组合

来自分类Dev

不了解Typescript中的重载

来自分类Dev

不了解界面中的方法

来自分类Dev

不了解OCaml中的符号

来自分类Dev

不了解Verilog中的类型

来自分类Dev

不了解Swift中的闭包示例

来自分类Dev

不了解SICP中的方案程序

来自分类Dev

不了解liunx内核中LWP的概念

来自分类Dev

不了解Node.js中的Cookie

来自分类Dev

不了解Oracle中的regexp_like

来自分类Dev

不了解Django框架中的构造网址

来自分类Dev

不了解Node.js中的Cookie

来自分类Dev

我不了解JavaScript中的递归

来自分类Dev

AddItem不填充组合框中的选项

来自分类Dev

了解组合子

来自分类Dev

了解C语言中的scanf

来自分类Dev

要将连字符作为元素包含在scanf()的scanset中,它应为列表中的第一个字符还是最后一个字符?

来自分类Dev

不了解在PHP中访问JSON数据的语法

来自分类Dev

不了解分布式路径中的路径

来自分类Dev

Angularjs $ http在响应中似乎不了解“ Set-Cookie”

来自分类Dev

不了解C ++ STL中std :: remove的结果

来自分类Dev

我不了解Prolog中的标签是什么

来自分类Dev

Lua中的table.sort:不了解此代码?

来自分类Dev

在python中解析xml-不了解DOM

来自分类Dev

不了解setRetainInstance(或Xamarin Android中的RetainInstance)如何工作?

来自分类Dev

我不了解JavaScript中的call()方法的要点

来自分类Dev

在字段路径中不了解“机会__c”关系。