【问题标题】:Why are %s and %c considered as the same type by `scanf()` function?为什么 %s 和 %c 被 `scanf()` 函数视为同一类型?
【发布时间】:2016-02-22 16:50:56
【问题描述】:
char c;
printf("%d", scanf("%s", &c)); // prints 1  
printf("%d", scanf("%c", &c)); // prints 1

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

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

我在这里错过了什么?

【问题讨论】:

  • @SedatKapanoglu,我认为不完全是。当说明符不正确时,更多的是关于scanf 的行为。
  • @SedatKapanoglu 我在这里发帖之前已经阅读过它,但无法得到我的答案
  • 这绝对不是提议的问题的重复。在提出的问题中,确实询问了这两个项目之间的差异。在这个问题中,发帖人非常错误地假设格式与scanf() 的返回值有关。
  • 重复是关于在printf() 中使用"%s""%c",而不是这里使用的scanf()。投票重新开放,因为 post 虽然相关,但不适用。
  • 这是无效代码。

标签: c string char scanf


【解决方案1】:

格式说明符%c%sscanf 系列函数中使用时都需要char* 类型的参数。

不同之处在于使用%c 最多会读取一个字符,而使用%s 会读取它找到的所有非空白字符。当使用%s 时,它还会在指针中添加一个终止空字符。

给定

char c;

使用

scanf("%s", &c);

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

事实

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

打印1 而不是崩溃是运气不好的问题。如果程序崩溃了,那就太好了。那你就知道程序错了。

【讨论】:

  • 关于 "%s" 所做工作的好/重要细节。
【解决方案2】:

%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));

【讨论】:

  • 那么为什么在 c 中会有 char 类型
  • @Prince Vijay Pratap 为什么char 存在?这是一个广泛的问题。所以我们可以一次用 1 个char 编码。 scanf(%c, &ch) 用于读取 1 charscanf(%9s, s) 最多读取 9 个 char 并形成一个字符串。
【解决方案3】:

有这样的定义

char c;

使用

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

导致undefined behavior*那么,输出不能以任何方式证明。


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

引用C11 标准,章节§7.21.6.2,与%s 格式说明符相关,

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

【讨论】:

    猜你喜欢
    • 2016-04-25
    • 2016-04-14
    • 1970-01-01
    • 2014-08-25
    • 2019-09-19
    • 2022-12-10
    • 1970-01-01
    • 2017-08-15
    • 2021-11-07
    相关资源
    最近更新 更多