为什么 C 函数 strlen() returns 一个错误的字符长度?

Why C function strlen() returns a wrong length of a char?

我的C代码如下:

char s="MIDSH"[3];
printf("%d\n",strlen(&s));

运行 的结果是 2,这是错误的,因为 char s 只是一个 'S'.

有人知道这个问题的原因和解决方法吗?

strlen 的签名是:

size_t strlen(const char *s);
/* The strlen() function calculates the
   length of the string s, excluding the
   terminating null byte ('[=10=]'). */

strlen 期望输入 const char array 是空终止的。但是当你传递一个 auto 变量的地址时,你不能保证这一点,因此你的程序有一个 undefined behavior.

Does anybody know why and how to solve this problem?

sizeof(char) 保证是 1。所以使用 sizeof1.

声明

printf("%d\n",strlen(&s));  

对于给定的案例没有任何意义。 strlen 需要一个空终止字符串,schar 类型并且 &s 不一定指向一个字符串。您得到的是程序未定义行为的结果之一。

要获得 s 的大小,您可以使用 sizeof 运算符

printf("%zu\n", sizeof(s)); 

这实际上是一个非常有趣的问题。让我们分解一下:

"MIDSH"[3]

字符串文字具有数组类型。因此,上面的代码将下标运算符应用于数组并计算出第 4 个字符 'S'。然后将其分配给 单字符变量 s.

printf("%d\n",strlen(&s));

由于 s 是单个字符,而不是实际字符串的一部分,因此上述代码的行为未定义。

strlen 函数将其参数视为指向字符序列的指针,其中该序列以 '[=11=]' 字符终止。

通过传递指向单个字符变量 s 的指针,您可以有效地说 &s 是此类序列中的第一个字符,但事实并非如此。这意味着 strlen 将在错误的前提下继续在内存中搜索,您将有 未定义的行为

当你使用 "char s=" 你在堆栈上为 's' 创建了一个新地址,这个地址不能被添加或减少!所以尽管你给 strlen 一个 char* 但它找不到'\0'添加 address.All 是错误的。 您应该将 strlen 与 char 的地址一起使用,该地址是 array.like:

char* s = "MIDSH";
printf("%d\n", strlen(s)); //print 5
s++;
printf("%d\n", strlen(s)); //print 4