繁体   English   中英

C 任意长度字符串

[英]C Arbitrary length string

我怀疑如何分配数组的长度

#include <stdio.h>
#include <string.h>

int main()
{
    char str[] = "s";
    long unsigned a = strlen(str);
    scanf("%s", str);
    printf("%s\n%lu\n", str, a);
    return 0;
}

在上面的程序中,我将字符串"s"分配给一个char数组。 我认为str[]的长度是 1。所以我们不能存储超过数组的长度。 但它的行为不同。 如果我使用scanf读取字符串,它将存储在str[]中而没有任何错误。 数组str的长度是多少?

示例 I/O:

Hello

Hello 1

您的str是一个用"s"初始化的char数组,也就是说,它的大小为2 ,长度为1 大小比长度大一,因为在末尾添加了 NUL 字符串终止符 ( \0 )。

您的str数组最多可以容纳两个char 尝试写入更多将导致您的程序访问 memory 超出数组末尾,这是未定义的行为。

但实际发生的情况是,由于str数组存储在 memory (在堆栈上)中的某个位置,并且 memory 区域远大于 2 个字节,因此您实际上可以写入末尾而不会导致崩溃。 并不意味着您应该这样做。 它仍然是未定义的行为。

由于您的数组大小为2 ,因此它只能容纳长度为1的字符串,加上它的终止符。 要使用scanf()并正确避免写入超出数组末尾,您可以使用字段宽度说明符:在%之后和s之前的数值,如下所示:

scanf("%1s", str);

当数组的大小由使用的初始值设定项确定时,在声明数组时未指定其大小。

在这个数组声明中

char str[] = "s";

使用字符串文字作为初始值设定项。 字符串文字是由包含的零终止字符终止的字符序列。 那就是字符串文字"s"有两个字符{ 's', '\0' }

它的字符用于按顺序初始化数组str的元素。

所以如果你会写

printf( "sizeof( str ) = %zu\n", sizeof( str ) );

那么 output 将为2 字符串的长度确定为终止零字符之前的字符数。 所以如果你会写

#include <string.h>
//...
printf( "strlen( str ) = %zu\n", strlen( str ) );

那么 output 将为1

如果您尝试在数组外写入数据,则会出现未定义的行为,因为不属于该数组的 memory 将被覆盖。 在某些情况下,您可以获得预期的结果。 在其他情况下,程序可能会异常完成。 那就是程序的行为是未定义的。

数组str的大小为 2:1 个字节用于字符“s”,一个用于终止 null 字节。 你正在做的是写到数组的末尾。 这样做会调用未定义的行为

当您的代码具有未定义的行为时,它可能会崩溃,它可能会 output 出现奇怪的结果,或者它可能(如在本例中)似乎正常工作。 此外,进行看似无关的更改,例如用于调试的printf调用或未使用的局部变量,可能会改变未定义行为的表现方式。

暂无
暂无

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

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