12

ユーザーが1つずつ入力する文字を格納するために使用しているchar配列バッファがあります。以下の私のコードは動作しますが、私が理解できないいくつかの不具合があります:

  1. printf を実行して Buffer の内容を確認すると、いっぱいになりますが、最後に文字化けが発生します
  2. char Buffer[8]; として宣言されているにもかかわらず、8 文字で停止しません。

誰かが私に何が起こっているのか、おそらくどうすればこれを修正できるのか説明してもらえますか? ありがとう。

char Buffer[8]; //holds the byte stream
int i=0;

if (/* user input event has occurred */) 
{
        Buffer[i] = charInput;
        i++;

        // Display a response to input
        printf("Buffer is %s!\n", Buffer);

}

出力:

tagBuffer は 1┬┬w!
tagBuffer は 12┬w です!
tagBuffer は 123w です!
tagBuffer は 1234 です!
tagBuffer は 12345 です!
tagBuffer は 123456=!
tagBuffer は 1234567 です!
tagBuffer は 12345678 です!

tagBuffer は 123456789 です!

4

7 に答える 7

29

文字列は \0 文字で終了する必要があります。そのため、ゼロ終端文字列と呼ばれます。

\0 を保持するために 1 文字余分に割り当てることも賢明です。

于 2008-11-06T23:07:35.897 に答える
8

printf() 関数に渡す唯一のものは、文字列の最初の文字へのポインターです。printf() には、配列のサイズを知る方法がありません。(ポインターは単なるメモリアドレスであるため、実際の配列であるかどうかさえわかりません。)

printf() およびすべての標準的な C 文字列関数は、文字列の末尾に 0 があると想定しています。たとえば、printf() は、関数に渡した char から始まり、0 になるまでメモリ内の文字を印刷し続けます。

したがって、コードを次のように変更する必要があります。

char Buffer[9]; //holds the byte stream
int i=0;

if( //user input event has occured ) 
{
        Buffer[i] = charInput;
        i++;

        Buffer[i] = 0; // You can also assign the char '\0' to it to get the same result.

        // Display a response to input
        printf("Buffer is %s!\n", Buffer);

}
于 2008-11-06T23:10:14.207 に答える
3

ゼロ終了に関する以前のコメントに加えて、自分のバッファーがオーバーフローしないようにする責任も受け入れる必要があります。コードが停止していないため、8 文字で停止しません。次のようなものが必要です(ジェレミーの提案に便乗):

#define DATA_LENGTH 8
#define BUFFER_LENGTH (DATA_LENGTH + 1)

char Buffer[BUFFER_LENGTH]; //holds the byte stream
int charPos=0;  //index to next character position to fill

while (charPos <= DATA_LENGTH  ) { //user input event has occured
    Buffer[i] = charInput;

    Buffer[i+1] = '\0';

    // Display a response to input
    printf("Buffer is %s!\n", Buffer);

    i++; 

}

つまり、環境が何を押し付けようとしているかに関係なく、最大長に達したらデータの受け入れを必ず停止してください。

于 2008-11-06T23:20:11.050 に答える
0

誰もこの可能性に言及していないのは奇妙です:

char Buffer[8]; //holds the byte stream
int i = 0;

while (i < sizeof(Buffer) && (charInput = get_the_users_character()) != EOF)
{
    Buffer[i] = charInput;
    i++;

    // Display a response to input
    printf("Buffer is %.*s!\n", i, Buffer);
}

printf() フォーマット文字列のこの表記は、表示される文字列の最大長を指定し、null 終了を必要としません (ただし、最終的には null 終了が最善の方法ですが、少なくともこのループを抜けた後は)。

ループはwhile単純な よりも妥当でifあり、このバージョンでは、バッファーの末尾をオーバーフローしないことが保証されます (ただし、末尾の NUL に十分なスペースを残すことは保証されません'\0'。それを処理する場合は、使用sizeof(Buffer) - 1してから NUL を追加します)。ループの後。

于 2008-11-07T06:28:56.910 に答える
0

C または C++ でプログラミングしている場合は、次のことを覚えておく必要があります。1) 文字列は \0 文字で終了します。2) C には文字列の境界チェックがなく、単なる文字配列です。

于 2008-11-06T23:11:58.023 に答える
-1

を使用して調べることもできますstringstream

于 2008-11-06T23:14:36.367 に答える