web-dev-qa-db-ja.com

(char)配列の終わりをマークするために「\ 0」が必要なのはいつ/なぜですか?

そこで、文字列を表す文字の配列を作成する方法の例を読みました。

ヌル文字\0は、配列の終わりを示すために配列の終わりに配置されます。これは必要ですか?

Char配列を作成した場合:

char line[100]; 

そして言葉を置く:

"hello\n"

その中で、文字は最初の6つのインデックスline[0] --line[6]に配置されるので、配列の残りの部分はとにかくヌル文字で埋められますか?

この本によると、たとえば、文字列定数"hello\n"を文字配列に入れて、\0で終了するのが慣例です。

たぶん私はこのトピックを完全には理解しておらず、啓蒙主義を喜んでいるでしょう。

5
Strict

(char)配列の終わりをマークするために「\ 0」が必要なのはいつ/なぜですか?

文字配列に文字列が含まれている場合は、終了ゼロが必要です。これにより、文字列が終了するポイントを見つけることができます。

あなたの例については、私が思うに、次のように見えます

char line[100] = "hello\n";

次に、初心者の場合、文字列リテラルには7文字が含まれます。これは文字列であり、終了ゼロが含まれます。この文字列リテラルのタイプはchar[7]です。あなたはそれを次のように想像することができます

char no_name[] = { 'h', 'e', 'l', 'l', 'o', '\n', '\0' };

文字列リテラルを使用して文字配列を初期化すると、そのすべての文字が初期化子として使用されます。したがって、この例に関連して、文字列リテラルの7文字は、配列の最初の7つの要素を初期化するために使用されます。文字列リテラルの文字によって初期化されなかった配列の他のすべての要素は、ゼロによって暗黙的に初期化されます。

文字列が文字配列に格納されている長さを確認する場合は、ヘッダー<string.h>で宣言されている標準のC関数strlenを使用できます。終了ゼロの前の配列内の文字数を返します。

次の例を考えてみましょう

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

int main(void) 
{
    char line[100] = "hello\n";

    printf( "The size of the array is %zu"
            "\nand the length of the stored string \n%s is %zu\n",
            sizeof( line ), line, strlen( line ) );

    return 0;
}

その出力は

The size of the array is 100
and the length of the stored string 
hello
 is 6

Cでは、文字列リテラルを使用して、文字列リテラルの終了ゼロを除く文字配列を初期化できます。例えば

char line[6] = "hello\n";

この場合、配列に格納されているシンボルのシーケンスには終了ゼロがないため、配列に文字列が含まれているとは言えません。

3

\0文字は、「配列の終わり」を示しません。 \0文字は、char配列に格納されているstringの終わりを示します。if(およびそのchar配列が文字列を格納することを目的としている場合のみ)。

Char配列は単なるchar配列です。独立した整数値を格納します(charは単なる小さな整数型です)。 char配列は\0で終わる必要はありません。 \0は、char配列では特別な意味はありません。単なるゼロ値です。

ただし、char配列を使用してstringsを格納する場合があります。文字列は、\0で終わる文字のシーケンスです。したがって、char配列を使用する場合文字列として文字列を\0で終了する必要があります。

したがって、\0が「必要」であるという質問に対する答えは、char配列に何を格納しているかによって異なります。 stringを格納している場合は、\0で終了する必要があります。文字列ではないものを格納している場合、\0は特別な意味を持ちません。

11
AnT

'\ 0'を文字配列として使用する場合は、必要ありません。ただし、文字配列を文字列として使用する場合は、「\ 0」を入力する必要があります。 Cには個別の文字列型はありません。

文字配列を宣言する方法は複数あります。

例:

char str1[]    = "my string";
char str2[64]  = "my string";
char str3[]    = {'m', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g', '\0'};
char str4[64]  = {'m', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g', '\0'};

これらの配列はすべて同じ文字列「mystring」を持っています。 str1とstr2では '\ 0'文字が自動的に追加されますが、他の2つでは、明示的に追加する必要があります。

4
MayurK

文字列の終わりをマークするには、ヌル文字が必要です。 Cは、文字配列の長さや文字列の長さに関する内部情報を格納しないため、null文字/バイト\0終了する場所をマークします。

これはstringsの場合にのみ必要ですが、–文字列を表さない通常の文字配列を使用できます。

たとえば、次のコードを試してください。

#include <stdio.h>

int main(void) {
    char string[1];
    string[0] = 'a';
    printf("%s", string);
}

文字配列は完全にデータで満たされていることに注意してください。したがって、終了をマークするnullバイトはありません。これで、printfはnullバイトに達するまで印刷を続けます。これは配列の終わりを超えた場所になるため、「a」だけでなく多くのジャンクを印刷します。

今、これを試してください:

#include <stdio.h>

int main(void) {
    char string[2];
    string[0] = 'a';
    string[1] = '\0';
    printf("%s", string);
}

文字列の終わりが明示的にマークされているため、「a」のみが出力されます。

2
Rushy Panchal

C文字列(文字を含み、「\ 0」文字で終了する配列)の長さは、(最初​​の)NULバイトを検索することによって検出されます。\0はゼロ文字です。 Cでは、主に文字列の終了を示すために使用されます。私はあなたに例を示します:

wordをファイルに書き込んだとしましょう。

Word = malloc(sizeof(cahr) * 6);
Word = "Hello";
fwrite(Word, sizeof(char), 6, fp);

ここで、Wordでは、「Hello」の5文字にスペースを割り当て、さらにその終了文字「\ 0」にもう1つスペースを割り当てます。 fpはファイルです。さて、最後の単語の後に別の単語を書きます。

Word2 = malloc(sizeof(cahr) * 7);
Word2 = "world!";
fwrite(Word2, sizeof(char), 7, fp);

それでは、2つの単語を読んでみましょう。

char buff = malloc(sizeof(char)*1000); // See that we can store as much space as we want, it won't change the final result
/* 13 = (5 chacater from 'Hello')+(1 character of the \0)+(6 characters from 'world!')+(1 character from the \0) */
fread(buff, sizeof(char), 13, fp); // We read the words 'Hello\0' and 'world!\0'
printf("the content of buff is: %s", buff); // This would print 'Hello world!'

この最後は、末尾の\0文字によるものであるため、[〜#〜] c [〜#〜]は、バッファに2つの分離された文字列があることを認識しています。その\0文字を両方の単語の末尾に配置せず、同じ例を繰り返すと、出力は"Helloworld!"になります。これは、多くの文字列メソッドおよび関数に使用できます。

1
wj127