2

宣言時に初期化する 2 つの char 配列を使用する C++ でプログラムを作成し、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;
}

上記のプログラムを ideone で実行したときの出力は次のとおりです。

lenv = 26 and lenc = 21

コードブロックを使用してウィンドウで実行すると、

lenv = 5 and lenc = 26

このような奇妙な行動の理由を教えてください...

4

3 に答える 3

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'};

nul char は追加されていません。文字列にすることもできます (二重引用符により、コンパイラは自動的にヌル ターミネータを追加します)。

char consonant[] = "bcd...z";

または、配列の最後に明示的に含めることができます。

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

それ以外の場合はstrlen()、メモリ内のどこかに値 0 のバイトが見つかるまで、配列の末尾を喜んで読み取ります。

于 2013-03-21T05:07:50.307 に答える
8

strlen任意の文字配列ではなく、文字列でのみ使用できます。

strlen() 関数は、s が指す文字列のバイト数を計算します。これには、終端の null バイトは含まれません。--IEEE1003

C++ 標準は、strlenC++ は C と同一であると述べていstrlenます。C 標準は次のように述べています。

この関数は、 sが指す文字列strlenの長さを計算します。-- C99 7.21.6.3

と:

文字列は、最初の null 文字で終了し、最初の null 文字を含む連続した文字列です。-- C99 7.1.1

したがって、渡すものはすべて、文字の配列だけでなくstrlen、実際にはstringであることを確認する必要があります。

于 2013-03-21T05:08:16.283 に答える
1

他の回答では、c スタイルの文字列を '\0' で閉じる必要があり、lenc=21おそらく何らかのオーバーフロー現象が発生している可能性が高いことが指摘されています (任意の n で n*SIZE_MAX+21 になる可能性があります)。

cで問題を適切に解決する方法に焦点を当てるには:

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

char consonant[] = "abcdefghijklmnopqrstuvxyz"; /* this is automatically '\0' terminated */
char vowel[] = "aeiou";

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

using namespace stdC++のみであることに注意してください。

一方、適切な C++ ソリューションは次のようになります。

#include<string>
#include<iostream>

std::string consonant("abcdefghijklmnopqrstuvxyz"); 
std::string vowel("aeiou");

int main()
{
    using namespace std; // if you wish using it, put it into a function

    int lenc = consonant.size();
    int lenv = vowel.size();
    cout << "lenv = " << lenc << " and " << "lenc = " << lenc << endl;
    return 0;
}
于 2013-07-29T15:04:38.690 に答える