strlen的奇怪行为

Vij*_*jay 2 c++

我在C++中创建了一个程序,其中我使用了两个char数组,我在声明时初始化,当我使用strlen()函数计算它们的长度时,我得到了奇怪的输出.代码如下所示

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

using namespace std;

char consonant[] = {'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'};
char vowel[] = {'a', 'e', 'i', 'o', 'u'};



int main()
{
    int lenv, lenc;
    lenc = strlen(consonant);
    lenv = strlen(vowel);
    printf("lenv = %d and lenc = %d\n", lenv, lenc);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在ideone上运行时上面程序的输出是

lenv = 26 and lenc = 21
Run Code Online (Sandbox Code Playgroud)

当使用codeblocks在Windows上运行时

lenv = 5 and lenc = 26
Run Code Online (Sandbox Code Playgroud)

请告诉我这种奇怪行为的原因......

Fat*_*ror 12

这里没有奇怪的举动.您的字符串不是以字符结尾的,因此该strlen()函数无法识别它们的结束位置.

当您初始化字符串时,如下所示:

char consonant[] = {'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'};
Run Code Online (Sandbox Code Playgroud)

没有添加nul char.您可以将其设为字符串(双引号会导致编译器自动附加nul终止符):

char consonant[] = "bcd...z";
Run Code Online (Sandbox Code Playgroud)

或者您可以在数组的末尾显式包含它:

char consonant[] = {'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z', '\0'};
Run Code Online (Sandbox Code Playgroud)

否则,strlen()将很乐意读取数组的末尾,直到它在内存中找到一个值为0的字节.


Dav*_*rtz 8

strlen 只能在字符串上使用,而不能在任意字符数组中使用.

strlen()函数应计算s指向的字符串中的字节数,不包括终止空字节. - IEEE1003

C++标准说strlenC++与C中的相同strlen.C标准说:

strlen函数计算s指向的字符串的长度. - C99 7.21.6.3

和:

是由封端的字符的连续序列,并且包括第一个空字符. - C99 7.1.1

因此,您必须确保传递给它的任何内容strlen实际上都是一个字符串,而不仅仅是一个字符数组.

  • @maja David的帖子非常清楚**字符串和字符数组之间的区别.所有字符串都是字符数组,但并非所有字符数组都是字符串.至于*你会叫什么东西,这是无关紧要的.标准所称的是什么是重要的. (2认同)
  • @maja:C标准也不知道你的记忆是如何布局的,或者是什么.虽然它可能都是你的计算机的位和字节,但它不是C.你在C中获得"连续字符序列"的唯一方法就是你在C程序中做了一些事情,保证你得到它,就像定义一个` char`数组.一旦你超越了这一点,所有的赌注都会被取消.您无法指出RAM中可能存在的任何随机垃圾,并尝试声称它是符合C的字符串. (2认同)