繁体   English   中英

为什么`scanf()`函数将%s和%c视为同一类型?

[英]Why are %s and %c considered as the same type by `scanf()` function?

char c;
printf("%d", scanf("%s", &c)); // prints 1  
printf("%d", scanf("%c", &c)); // prints 1

我不明白为什么这两个语句都打印相同的值1

据我所知,在早期匹配失败的情况下, scanf()返回成功匹配和分配的输入项数,甚至返回零。 那不是错配的情况吗?

我在这里想念什么?

当在scanf函数系列中使用时,格式说明符%c%s期望使用char*类型的参数。

区别在于,使用%c最多可以读取一个字符,而使用%s可以读取找到的所有非空白字符。 使用%s时,它还将在指针中添加一个终止的空字符。

给定

char c;

使用

scanf("%s", &c);

这是一个问题,因为&c只能写入一个有效字符。 因此,它导致使用程序不应该使用的内存,从而导致未定义的行为。

事实

printf("%d", scanf("%s", &c))

打印1而不是崩溃是一个不幸的问题 如果程序崩溃了,那就太好了。 然后,您将知道该程序是错误的。

%s and %c are used for different types

是不正确的。 他们都期望使用相同的类型: char *


"%c"期望一个char *指向1个char

"%s"期望一个char *指向足以容纳字符串的数组。 这必须至少为2个char OP代码可能会写在c 超出变量空间写是未定义的行为。


代替

char s[10];
printf("%d", scanf("%9s", s));
char c;
printf("%d", scanf("%c", &c));

像这样的定义

char c;

使用

scanf("%s", &ch);  // "" s added

导致不确定的行为 *然后,无法以任何方式证明输出的合理性。


注意: %s格式说明符期望相应的参数是一个足够长的char数组的指针。 否则,将出现内存边界溢出,这将导致UB。

要引用与%s格式说明符有关的C11标准第§7.21.6.2章,

[...]相应的参数应为指向字符数组的初始元素的指针,该元素应足够大以接受序列和终止的空字符,该字符将自动添加。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM