0

文字列は、隣接するメモリアドレスを持つ単なる文字の配列であることを知っています。したがって、文字配列がある場合:

char s[5];
s[0] = '1';
s[1] = '2';
s[2] = '3';
s[3] = '4';
s[4] = '5';

s[1] の文字配列を "5" に変更すると、そのような配列を出力すると "15345" が返されます。今私の質問は scanf と strtol 関数についてです。異なるサイズの文字列を使用して scanf を 2 回使用して配列 s に値を挿入すると、strtol 関数が配列全体を変換しないのはなぜですか?

例として私のコードを次に示します。

#include <stdio.h>
#include <stdlib.h>

int main(){
    char bytes[5];
    printf("enter size 1: ");
    scanf("%s", bytes);

    printf("the size is: %ld\n", strtol(bytes, NULL, 10));

    printf("enter size 2: ");
    scanf("%s", bytes);

    printf("the size is: %ld\n", strtol(bytes, NULL, 10));

    return 0;

}

次のユーザー入力を想像してみてください。

10000

プログラムは「サイズは10000です」と出力します

次に、ユーザーは次のように入力します。

100

次に、プログラムは「サイズは100です」と出力します

「サイズは1000です」と再び出力されないのはなぜですか?最初の入力からのバイトの残りの配列要素は変更されず、strtol は配列の残りの部分を正しく変換する必要がありますか?

私の考えでは、プログラムが 10000 の最初の入力をバイト配列に格納すると、その瞬間は次のようになります。

バイト = {1,0,0,0,0}

次に、ユーザーが 100 を入力すると、最初の 3 つの要素の値のみが変更され、配列の残りの部分は同じままであるため、配列は同じように見えます。

バイト = {1,0,0,0,0}

その strtol を使用すると、配列全体が 10000 に変換されますよね?

scanf は、値を同じメモリ アドレスに格納するときに、配列の残りの部分を本質的に「空」にしますか?

4

3 に答える 3

1

文字列の重要なプロパティを省略しました。それらは NUL バイト、別名 で終わる必要があり'\0'ます。

つまり、「10000」を 5 バイト配列に書き込むと、規則に違反したことになります。

この関数は、スペースに到達するまでscanf文字を文字列に変換します。%sこれは安全な操作ではありません。のようなもので変換の長さを制限する必要がありますscanf("%4s", bytes)。scanf ドキュメントには次のように書かれているためです。

文字列入力の変換では、入力の終わりを示すために終端のヌル バイト ('\0') が格納されます。最大フィールド幅には、このターミネータは含まれません。

scanfドキュメントのその行は、サイズ2で「100」を取得する理由も説明し{'1', '0', '0', '\0'}ていますbytes。配列に書き込まれたためです。

于 2015-10-04T20:18:49.120 に答える
1

簡単な答え:

scanf()char配列を.で終了します\0。配列の残りは空にしません。

これを証明する簡単なプログラムを次に示します。

#include <stdio.h>

int main(void) {
    char str[100];

    scanf("%s", str); // Inputing 0123456789
    printf("String : %s\n", str);

    scanf("%s", str); // Inputing 01234
    printf("String 2 : %s\n", str); // str should be { '0', '1', '2', '3', '4', '\0', '6', ... }

    printf("Proof : %s", str + 6); // Outputs 6789
    return 0;
}

scanf見つかったもので配列をオーバーライドし、最後に a を追加します\0。したがって、アレイの残りの部分はそのまま残り、引き続きアクセスできます。

あなたの状況では、配列はメモリ内で次のようになります。

  • 2 番目の前scanf(): { '1', '0', '0', '0', '\0' }// 1000

  • 2 番目以降scanf(): { '1', '0', '0', '\0', '\0' }// 100

于 2015-10-04T20:24:45.100 に答える