2012-05-08 13 views
3

配列の文字列を読みたい。配列のサイズは、実行時にmallocまたはallocを使用して決定されます。つまり、文字列の数が入力として受け入れられます。私は次のコードを試しましたが、うまくいきません。
Cで文字列の配列を読み取る

char *array; 
array=(char*)malloc(sizeof(char)*t); //t is the size of array 
for(int temp=0;temp<t;temp++) 
{ 
    gets(a[temp]); 
} 

整数の配列の場合も同様です。
解決策を見つけるのを手伝ってください。

+0

sizeof(char)は冗長です。それはC標準によって定義され、1であることが要求されます。 – glglgl

+0

@glglgl right、sizeof(char)は冗長です。代わりにmalloc(1 * t)を使うべきです。 – Jaguar

+0

なぜ 'malloc(t)'だけではないのですか? :-) – glglgl

答えて

5

Cには、文字列を格納するための自動組み込みサポートがありません。「文字列」の変数はなく、自動的に適切な文字数になるように拡張できます。自分でメモリを割り当てる必要があります。

あなたは今何をしているのですか、文字ポインターの適切な数のための場所を割り当てていますが、どの文字も割り当てていません。したがって、gets()コールは割り当てられていないメモリへの書き込みです。これは未定義の動作です。整数は完全に1つの割り当てに完全に収まるので、同様のコードが整数のために働いたのです。文字列はより複雑なので、より多くの作業をする必要があります。

これらの文字列の長さに既知の上限がある場合は、固定長の一時バッファを使用して、必要なサイズを知った後、新たに割り当てられた動的メモリにコピーできます。そのような境界がない場合、同じ概念を繰り返す必要があります。固定ブロックを読み込んでそれを格納し、行末が見つからない場合は別のブロックを読み込み、realloc()を使用してこの文字列のメモリ割り当てを増やし、文字を入力し、行が終了するまで繰り返します。

補足として、gets()は、プログラムのバッファオーバーランからの保護をサポートしていないため、使用しないでください。同じページに書かれているfgets()を使うほうがずっと良いです。

1

割り当てられるのは、ゼロ終了フォーマットで格納された、正確に1つの文字列のためのスペースです。

複数の文字列の配列を格納する場合は、malloc()の配列にchar *の配列をいくつか追加する必要があります。

さらに、サイズ制限がないので、gets()は安全ではありません。代わりに、fgets()を使用してください。それは次の署名を持っています:

char *fgets(char *restrict s, int n, FILE *restrict stream); 

ストリームを望むので、stdinを与えてください。

だから1行を読むための最良の方法は、

char * read_one_line(uint32_t maxbufsize) 
{ 
    char * s = malloc(maxbufsize); 
    if (!fgets(s, maxbufsize, stdin)) { 
     free(s); 
     return NULL; 
    } else { 
     char * s2 = realloc(s, strlen(s)+1); // +1 for the NUL at the end 
     if (s2) { 
      return s2; 
     } else { 
      return s; // should never happen as the memory block is shrinked 
     } 
    } 
} 

この機能が適切に読んだ後、それをリサイズし、一行に必要なメモリを割り当て、適切な時期に再びそれを解放するために、呼び出し元にそれを残しています。

+0

入力の文字列の配列を読み取る他の効率的な方法は何ですか? – Jaguar

+0

私の編集を参照してください。ここでは、1行の読み方を示しています。 – glglgl

1

あなたが最初の文字列の配列(char*)のためのスペースを割り当てる必要があります。

char **array; 
array = (char**)malloc(sizeof(char*)*t); 

次にあなたがそれらのそれぞれのためのスペースを割り当てる必要があります(レッツ・50は、これらの文字列の文字の最大カウントされるように):

int i = 0, m = 50; 
for (i = 0; i < t; ++i) 
    array[i] = (char*)malloc(sizeof(char)*51); // 51 = 50 characters + '\0' 

そして、あなたがやりたいこと行うことができます。

for(i = 0; i < t; ++i) 
    scanf("%50s", array[i]); 

getsの代わりにと指定しての幅%50s = 50文字+ '\0')を使用することをお勧めします。

0

文字配列の末尾には、NUL文字が必要です。

allocまたはmalloct+1バイトのメモリを割り当てます。

tバイトの文字と、終端の1バイトのNUL文字です。

あなたforループ、ループのすなわち外側の後、ちょうどあなたが仕事でそれを取ることができる

a[temp] = '\0'; 

を書きます。

私はうまくいきたいと思います。

それは、その後、アレイを印刷すると、文字列を取得します。この

char *a = malloc(sizeof((char)*(t+1)));//t is number if characters 
int temp; 
for(temp=0; temp<t; temp++) { 
    gets(a[temp]); 
} 
a[temp] = 0; 

のようになります。

printf("%s",a); 
+0

あなたは、すべての文字に対して 'malloc'を呼びたいと思っていますか? – glglgl

+0

mallocは1回だけ(t + 1)回 –

+0

あなたの文脈で「時間」は何を意味しますか?バイトを意味しますか? – glglgl

関連する問題