4

Cプログラミングでは、 scanf() 関数を使用してポインタの配列に値を取得することはできませんが、

int main()
{
char *names[6];
int loop;
scanf("%s",names[1]);
printftf("\n%s",names[1]);
}

入力をプログラムとして与えると機能しますが、入力を保存していると思いますが、指定された入力として出力を正しく出力します。その後、セグメンテーション違反が発生します...しかし、ループで同じことを行うと6キャラゲットで

int main()
{
 char *names[6];
 int loop;
 for(loop=0;loop<6;loop++)
 scanf("%s",names[1]);
 for(loop=0;loop<6;loop++)
 printf("\n%s",names[1]);
 }

うまくいきません 答えを教えてください...

4

2 に答える 2

11

問題は、これらの名前にスペースを割り当てていないことです。で使用する場合は、配列内の各要素を初期化する必要がありますscanf

char* names[6];
for( int i = 0; i < 6; ++i )
    names[i] = malloc( 256 * sizeof *names[i] ); // or some other max value

scanf( "%s", names[1] );

そうしないと、これらのポインターはメモリ内の任意の場所を指し、それらの場所を読み書きしようとすると、最終的にセグメンテーション違反が発生します。

于 2012-12-31T05:14:47.077 に答える
4

コードnamesには、char への 6 つのポインターの配列があります。これで、これらのポインターのそれぞれに、新しい文字列の開始点 (最初の文字のアドレス) を格納できるようになりました。これは、変数に 6 つの異なる文字列の開始アドレスを格納できることを意味しますnames

ただし、ループを使用してこれらの各文字列を初期化する場合は、各文字列の長さをマシンに通知する必要があります。これにより、連続したアドレス ブロックを割り当てることができ、その最初のアドレスをポインタに格納して、ストリング。したがって、文字列を格納するのに十分だと思われる特定のサイズを割り当てる必要があります (例: 256 バイト、1 バイトは 1 文字)。これがないと、マシンは文字列のすべてのバイトを格納する場所を認識できず、不正なメモリ アクセスが原因でセグメンテーション エラーがスローされます。

したがって、これを行うには、6 つのポインターのそれぞれに、文字列を格納するためのスペースを割り当てる必要があります。これは、を使用してループで実行されますmalloc()。@K-ballo のコードに基づく:

char* names[6];
int max_length = 256; // The maximum length you expect
for( int i = 0; i < 6; ++i )
    names[i] = malloc( max_length * sizeof(char) ); // allocates max_length number of bytes

scanf( "%s", names[1] );

したがって、基本的に、max_lengthそれぞれが参照する連続した char アドレスの 6 つの異なるブロックがありますnames[i]。これを行うと、scanf()標準入力からバイトが読み取られ、names[1] によって参照されるメモリ内のこれらの割り当てられたバイトに入れられます。

最初はこれをすべて理解するのに苦労したので、精巧な説明が役立つと思っただけです. :)

于 2012-12-31T05:57:54.493 に答える