2011-02-08 15 views
0

char*(文字列)配列を構造体に追加する場合、構文はどのように見えるのですか?構造体の文字配列

一つは、例えば、配列の長さの制限を設定ない

struct someStruct 
{ 
    char **someStrings; 
} 

someStringの各メンバーに10文字の制限を設定しますか?

+0

someStringに10個の文字列を格納するか、各文字列に10個の文字を格納するように制限しますか? – mkb

+0

各文字列に10個の文字を入れる – jarryd

+0

私はあなたが本当にCでこれを行うことができるとは思わない、とにかく自動的にではない。配列のサイズは、その型の一部ではありません(Goのように)。 – mkb

答えて

2

あなたが必要になりますどのように多くの文字列を事前に知っている(M、それを呼び出す)と、各文字列の最大長(Nそれを呼び出す)場合は、あなただけのcharの2D配列を宣言したい:

#define M ... // number of strings 
#define N ... // max length of each string 

struct someStruct 
{ 
    char someStrings[M][N+1]; // +1 for 0 terminator 
    ... 
}; 
をその後

#define N ... 

struct someStruct 
{ 
    char (*someStrings)[N+1]; 
    size_t numStrings; 
    ... 
}; 

、あなたを割り当てる必要があります。

あなたが必要がありますどのように多くの文字列を知っているが、最大の長さを知っていない場合、あなたはcharの配列へのポインタを宣言することができます文字列配列の場合は、次のようにします。

struct someStruct s = {NULL, 0}; 
size_t count = getNumStrings(); 
s.someStrings = malloc(sizeof *s.someStrings * count); 
if (s.someStrings) 
    s.numStrings = count; 

そして今、あなたは文字列の配列としてsomeStringsを扱うことができます:あなたは、アレイで行われている

strcpy(s.someStrings[i], "foo"); 
printf("%s\n", s.someStrings[j]); 
s.someStrings[i][j] = 'a'; 

は、そうのようなメモリを解放:

free(s.someStrings); 

NOTE:配列へのポインタを扱うときには、添字を適用する前にポインタを逆参照する必要があります。あなたは通常、適切に配列のi番目の要素にアクセスするために(*a)[i]を記述する必要がありますコード

T (*a)[N]; 
a = malloc(sizeof *a); // allocates a single N-element array of T 

与えられた(*a[i]は、私たちがここに欲しいものではありませんこれは、*(a[i])として解析します)。ただし、a[0]*aに相当します。 aに添字を暗黙的に逆参照するので、a[0][i](*a)[i]に相当します。我々は

a = malloc(sizeof *a * M); // allocates M N-element arrays of T 

としてそれを割り当てた場合、我々はなどa[0][0]a[0][1]、などなどa[0]a[1]、など各配列、および各配列の各要素を参照することができますが、任意のポインタの体操が表示されていない理由ですこと上記のコード。

あなたはどのように多くの文字列や、各文字列の最大長さがわからない場合、あなたはそのように、2段階の割り当てを行う必要があるでしょう:

struct someStruct 
{ 
    char **someStrings; 
    size_t numStrings; 
    size_t maxLength; 
}; 

struct someStruct s = {NULL, 0, 0}; 
size_t count = getNumStrings(); 
s.maxLength = getMaxLength(); 
s.someStrings = malloc(sizeof *s.someStrings * count); 
if (s.someStrings) 
{ 
    size_t i; 
    s.numStrings = count; 
    for (i = 0; i < s.numStrings; i++) 
    { 
    s.someStrings[i] = malloc(sizeof *s.someStrings[i] * s.maxLength + 1); 
    if (s.someStrings[i]) 
     // initialize string value here 
    } 
} 

ここでも、あなたのようにsomeStringsを扱うことができます通常の2D配列:割当て同様

strcpy(s.someStrings[i], "foo"); 
printf("%s", s.someStrings[j]); 
s.someStrings[i][j] = 'a'; 

、割り当て解除は、2段階のプロセスである:

for (i = 0; i < s.numStrings; i++) 
    free(s.someStrings[i]); 
free(s.someStrings); 

最初の2つのメソッドとは異なり、このメソッドでは文字列がメモリ内で連続しているとは限りません。

文字列の数と各文字列の最大長を手動で追跡する必要があります。その情報をポインタ値だけから得る方法はありません。

+0

これは本当に便利でした;) – jarryd

0

char **は、文字列の配列です。単純な文字列はchar *です。

長さを制限する場合は、char someString[11]を使用できます。 (最後にヌル文字を含めるには+1)。

+0

文字列の配列を必要とし、各文字列を例えばに制限します。 10文字? – jarryd

1
#define NUM_STRINGS 5 // for example 
#define STRING_LENGTH 11 // for example 

struct someStruct 
{ 
    char stringArray[NUM_STRINGS][STRING_LENGTH]; 
} 

あなたの質問とあなたのコメントから他の質問には、このように見えます。あなたの文字列配列はこの場合5つの文字列を保持し、各文字列は10文字とヌル終端文字を保持します。あなたは定義なしでそれを行うこともできますが、定義によって、後でサイズを変更しなければならない場合に変更が容易になります。