Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是scanf(“%[^\n]%*c”和“s”);真的吗?_C_Scanf - Fatal编程技术网

什么是scanf(“%[^\n]%*c”和“s”);真的吗?

什么是scanf(“%[^\n]%*c”和“s”);真的吗?,c,scanf,C,Scanf,我知道[^\n]是一个分隔符,它使scanf扫描所有内容,直到按下“enter”键。但是我不知道“%[^\n]%*c”的其余部分用于什么。另外,为什么我们必须在scanf函数中提到“&s”而不是“s” 我试着运行这个: char s[100]; scanf("%[^\n]s",s); scanf("%[^\n]s",&s); 以上两种scanf语句对我的作用完全相同。如果它们之间有什么区别,那是什么 还有为什么我更喜欢scanf(“%[^\n]]*c”和&s)以上声明?sc

我知道[^\n]是一个分隔符,它使scanf扫描所有内容,直到按下“enter”键。但是我不知道“%[^\n]%*c”的其余部分用于什么。另外,为什么我们必须在scanf函数中提到“&s”而不是“s”

我试着运行这个:

char s[100];
scanf("%[^\n]s",s);      
scanf("%[^\n]s",&s);
以上两种scanf语句对我的作用完全相同。如果它们之间有什么区别,那是什么

还有为什么我更喜欢scanf(“%[^\n]]*c”和&s)以上声明?
scanf(“%[^\n]s”和&s)有很多问题:

不检查返回值。
无超限保护
没有消耗
'\n'


不需要
中的
s
“%[^\n]s”

格式错误的类型
&s

scanf(“%[^\n]s”,s)只有一个问题(最后一个)

使用
fgets(s、s、stdin的尺寸)


  • 不检查返回值
如果不检查返回值,则读取成功未知,
s
的状态不确定

  • 无超限保护
输入第100个字符时会发生什么情况?-“很糟糕,不好,不好。”

  • 没有消耗
    '\n'
“\n”
保留在
stdin
中,以扰乱下一次读取

  • 仅在
    '\n'
    上未分配
    s
如果输入以
'\n'
开头,scanf()将返回,并且
s
将保持不变。它没有被分配到

  • “%[^\n]s”
“s”
不是说明符“%[^\n]”
的一部分。放下它

  • 格式错误的类型
    &s

%[…]
匹配的是
char*
,而不是指向
char[100]
的指针,比如
&s
(UB)。

您可以使用scanf(“%s”,s”)将字符串作为C中的输入。但是,它只接受字符串,直到找到第一个空格为止

为了将一行作为输入,可以使用scanf(“%[^\n]%*c”,s);其中s定义为字符s[MAX_LEN],其中MAX_LEN是s的最大大小。这里,[]是扫描集字符^\n表示在未遇到换行符之前进行输入。然后,使用这个%*c,它读取换行符,这里,used*表示这个换行符被丢弃


注:输入字符和字符串后,用上述语句输入句子将不起作用。这是因为在每一行的末尾都有一个新行字符(\n)。因此,声明是:scanf(“%[^\n]]*c”,s);将不起作用,因为最后一条语句将从上一行读取换行符。这可以通过多种方式处理,其中之一是:scanf(“\n”);在最后一条语句之前。

对于已衰减为指针的数组,如在scanf调用中,
s
&s
、和
&s[0]
都引用相同的地址。您在哪里听说您应该更喜欢
scanf(“%[^\n]]*c”和&s)?非常相似,可能重复的
scanf(“%[^\n]%*c”、&s)
类似于
get()
。两者都不用。使用
fgets(s,sizeof s,stdin)
。您应该更喜欢
fgets()
,但是如果必须
%[^\n]
是一个
[…]
(字符类)格式说明符,它匹配所有
'^'
('not'当包含第一行时)的字符。(允许读取空白)。
“*”
字符是赋值抑制修饰符,允许读取/放弃该转换说明符的类型(此处为单个字符,例如
“\n”
)。当使用
“*”
时,任何转换都不会添加到匹配计数(例如返回)。因为调用后输入缓冲区中剩余的内容不取决于使用的转换说明符(或读取/丢弃其他字符)。只需使用
fgets
并通过覆盖nul终止字符来修剪换行符,这将省去许多麻烦。合理的建议。当然,如果不是因为滥用scanf的陷阱,我会损失30%的问题。
:)
我是这里的新手。谢谢你迅速而详尽的回答,但如果你能对你列出的要点做更多的解释,那会对我有更大的帮助,因为我仍然无法理解。@DavidC.Rankin今天
scanf()
,我想要你的图片集
:)
@Alagusankar-拿子弹1-如何修复?(检查报税表)。Bullet 2-使用字段宽度修饰符请参见,Bullet 3-在非
'\n'
的字符集合之后请求匹配文字
's'
,Bullet 4从3开始,Bullet 5-解释
%[…]
本身就是一个完整的转换说明符,后面的
's'
必须与输入中的文本
's'
相匹配(您的使用是多余的)。(或使用
fgets()
)简化生活)
if (fgets(s, sizeof s, stdin)) {
  s[strcspn(s, "\n")] = 0; // Lop off potential ending \n
  // Success
} else {
  // failure
}