为什么 strlen() 函数给出错误的值

Pra*_*eja 2 c input string-length strlen

我不明白为什么只为第一个字符串strlen()给出错误的值(即9:)。之后,值正确出现。

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

int main() {
    int m, i, j;
    i = 2;
    j = 5;
    char a[i][j];
    for (i = 0; i <= 2; i++)  {
        scanf("%s", a[i]);
    }
    m = strlen(a[0]);
    printf("%d\n", m); //here the problem is coming//
    m = strlen(a[1]);
    printf("%d\n", m);
    m = strlen(a[2]);
    printf("%d\n", m);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输入:

heyman
jack
bro
Run Code Online (Sandbox Code Playgroud)

输出:

9
4
3
Run Code Online (Sandbox Code Playgroud)

Bar*_*mar 10

每行a只有 5 个字节。当您读heyman入时a[0],它会溢出到a[1]. 所以你有了:

a[0] = "heyma"
a[1] = "n\0"
Run Code Online (Sandbox Code Playgroud)

然后当你读入时a[1],你有

a[0] = "heyma"
a[1] = "jack\0"
Run Code Online (Sandbox Code Playgroud)

请注意, 中没有空终止符a[0]。因此,当您调用 时strlen(a[0]),它会越过结尾a[0]并继续搜索a[1]空字节。有 5 个字节 ina[0]和 4 个字节a[1],因此长度为 9。从技术上讲,这是未定义的行为,但在实际实现中会发生这种情况,因为二维数组是连续的。

此外,当您读入时,a[2]您完全在a数组之外,从而导致未定义的行为。

  • 标准中的附录 J.2 明确列出了这种越界多维数组访问作为未定义行为的示例:“数组下标超出范围,即使对象显然可以使用给定下标访问(如给定声明 int a[4][5]) 的左值表达式 a[1][7]` (3认同)

Joh*_*ith 7

由于您的数组具有长度,因此[2][5]您可以存储最多2长度为 length 的4单词\0,因此除了字母之外,每个单词还具有终止字符。

你有作为输入heyman意味着你写了太多的字母并且没有足够的空间来存储\0. 尝试使用较短的单词或将长度从 更改57

此外,您将3单词存储在 length 数组中2,长度是指存储的元素数量,而不是您可以达到的数量。长度2将有可用位置01因此当您将第三个单词作为输入传递时,您试图在数组边界之外写入。