scanf("%3s", str) 在 c 中只有 1 个输入字符

问题描述 投票:0回答:3
#include<stdio.h>

int main(void) {
   char str[3];
   scanf("%3s", str);
   return 0;
}

如果只输入一个字符,str[2]的内容是什么?这是未定义的行为还是所有剩余字符都会用 ' ' 填充?

我尝试了这个,其余的字符都是“”,但这可能是编译器特定的。

arrays c string scanf
3个回答
0
投票

C 字符串是字符数组。该字符串以空终止字符终止。

要存储 3 个字符 + 空终止字符,您需要 4 个元素的字符数组。

如果用户输入

scanf
或更多字符,您的
3
将调用未定义的行为。

如果我只输入一个字符,

str[2]
的内容是什么?这是 未定义的行为或者所有剩余的字符都将被填充 ' '?

由于您的变量具有自动存储持续时间,因此值

str[2]
无法确定(可以是任何值)。

如果

str
数组具有静态存储持续时间(即在具有
static
属性的函数内部定义或者是全局的),那么它将具有
0
值(因为未初始化的静态存储持续时间对象在调用之前被归零)
main
功能已完成。


0
投票

处理

s
转换的规则,在 C 2018 7.21.6.2 中说:

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

这告诉我们,如果您输入一个(非空白)字符(并且可能后面跟着一个空白字符或某种输入结束指示),该字符将被放入

str
(位于
str[0]
),并在其后的
str
中放入一个空字符。

标准没有规定在这些之后向

str
的任何元素写入任何内容。

请注意,

%3s
最多允许读取三个字符,在这种情况下,
str
中需要四个元素,以便它可以容纳三个字符和终止空字符。


0
投票

如果只输入一个字符,str[2]的内容是什么?

内容是不确定的,因为这是一个从未初始化的本地数组。

scanf
(系列)与
%3s
一起使用仅保证最多读取 3 个字符 - 但如果用户键入一个字母,然后输入一个空格字符,
scanf
将停在那里,仅读取输入的一个字符。

它还在输入后附加一个空终止符,因此如果用户恰好键入 3 个字符然后按 Enter 键,

scanf
会将空终止符写入越界。

您可以自己尝试使用这个打印缓冲区的二进制内容的小程序:

#include <stdio.h>

int main(void) 
{
  char str[4]={1,2,3,4};
  scanf("%3s", str);
  printf("%.2X %.2X %.2X %.2X", str[0], str[1], str[2], str[3]);
}

这里为了说明目的,我将大小更改为 4 并初始化了数组。

  • 输入:

    A <enter>

    输出:
    41 00 03 04

    41
    'A'
    的ASCII值,
    00
    是附加的空终止符,
    03 04
    是之前内存中的内容。如果这是一个未初始化的数组,那么这些值可能是“垃圾”。正如我们所看到的,
    scanf
    not 对数组的剩余部分进行“零填充”(例如
    strncpy
    会做的事情)。

  • 输入:

    ABC <enter>

    输出:
    41 42 43 00

    41 42 43
    是字母,
    00
    是附加的空终止符。如果这是一个大小为 3 的数组,那么它就会越界。
    scanf
    不知道数组有多大,所以如果我使用
    scanf
    并传递给它一个
    %3s
    数组,我就会对
    char [3]
    撒谎,说“嘿,你可以在这里存储3个字符+空终止”,即使没有任何空间了。

© www.soinside.com 2019 - 2024. All rights reserved.