web-dev-qa-db-ja.com

Cで文字配列の配列を保持する配列の作成

私のCは現時点ではさびているだけなので、かなり基本的なものと思われるものを作成できません。

この投稿の文字列として文字配列を参照させてください。それは私とあなたの両方にとって物事を明確にするでしょう。

私が持っているのは、1つ以上の文字列を保持できる配列です。たとえば、{"ab"、 "cd"、 "ef"}。文字列の配列の複数のバージョンを格納する別の配列を作成したい。 {{"ab"、 "cd"、 "ef"}、{"gh"、 "ij"}、{"kl"}}のようなものです。

私が今持っているものは:

char *arrayOfStrings[50]; // a single array to hold multiple strings
char **arrayOfArraysOfStrings[10]; // array to hold multiple snapshots of arrayOfStrings

文字列の配列は時間とともに変化し、基本的にarrayOfStringsの履歴スナップショットを保持するために文字列の配列の配列を使用しています。私の問題は、データのスナップショットアレイにアクセスする必要があるときに発生します。これは、スナップショット配列に何かを入れなければならないコードです:

arrayOfArraysOfStrings[input_index] = arrayOfStrings; // you can assume input_index is updated correctly, I've already checked that.

スナップショット配列のコンテンツにアクセスして印刷しようとすると、最新のarrayOfStringsからの情報のみが印刷されるため、これは間違っているようです。私がこれを目指していたのは、後でアクセスできるように、arrayOfCharsがスナップショット配列のエントリで指しているアドレスを保存することでした。

現在、スナップショット配列内のエントリへのアクセスは次のように実行されます。

arrayOfArraysOfChars[historicalIndex][indexOfTargetChar]

私が答えを探しているいくつかの質問があります:

  1. 私が概説した方法は、私がやろうとしていることに対して適切ですか、または私の全体的なロジックに欠陥がありますか?
  2. 現在のコードで何が間違っているのですか?どうすれば修正できますか?
  3. これを行うより良い方法はありますか?もしそうなら、配列の初期化、配列への追加、および配列からの読み取りはどのように機能しますか?

-編集4/18--問題の一部は、arrayOfArraysOfStringsのポインターがarrayOfStringsが指しているのと同じものを指すように設定していることです。 arrayOfStringsが編集されるため、これは悪いことです。 2D配列を複製するには何らかの方法が必要です。できれば、arrayOfStringsが指すメモリの新しいブロックを単に割り当てることによって。

15
Dae314

両方の配列に1対多のポインターがあります。

char arrayOfChars[50]; // a single array of characters
char *arrayOfArraysOfChars[10]; // array to hold multiple single arrays of characters

ArrayOfCharsはバッファのように使用されているため(新しいデータが常に最初にそこに送られます)、文字列のコピーをarrayOfArraysに保存する必要があります。 POSIX関数strdupはここで役立つはずです。

通知&および*は逆なので、&*および*&絶対に何もしません。

また、arrayOfArraysを文字通り作成することもできます。

char arrayOfChars[50]; // a single array of characters
char arrayOfArraysOfChars[10][50]; // array to hold multiple single arrays of characters

このセットアップでは、strcpyを使用してデータをarrayOfArraysにコピーする必要があります。


編集内容を読んだ後、real simpleを開始する必要があると思います。そして、FWIW変数名はハンガリーの間違った種類です。

私があなたがしようとしていると思うことのために、私はただ1つのchar配列から始めます。これはメインのbufferになり、入力および検査される文字列を保持します。

enum { BUFSZ = 50 };
char buf[BUFSZ + 1];

次に、fgetsまたは何でも使用できます。

fgets(buf, BUFSZ, infile);

これらを配列に保存するには、自動トリミングにstrdupを使用します。文字列のほとんどが2文字の長さになる場合、それぞれに48バイトの余分なバイトを使用したくありません。したがって、charポインター(文字列)の配列。

enum { STRVSZ = 40 };
char *strv[STRVSZ + 1];
int i;
i = 0;
strv[i] = strdup(buf);
strv[i+1] = NULL; // This makes it an "argv-style" NULL-terminated array of strings
++i; // i is now the index of the next element, and a count of elements already added

strvの各要素は、charポインターです。しかし、健全性を保つために、abstract awayその気を散らす詳細の一部を少しの間、stringsを別のデータ型として扱います。

これらのリストを作成するために、同じことを繰り返します。しかし、ポインターの配列の複製を作成するstrdup- type関数がないため、割り当てとコピーを分離する必要があります。

enum { STRVVSZ = 20 };
char **strvv[STRVVSZ + 1];
int j;
j = 0;
strvv[j] = calloc(i+1, sizeof *strvv[j]); // assuming i is the count of elements 
memcpy(strvv[j], strv, i * sizeof *strvv[j]);
++j; // j is now the index of the next string-pointer array in the array-of-same,
     // and a count of elements already added.

今、私の名前はあなたの名前と同じくらいばかげていますが、それらは短い!です

17
luser droog

配列の意味を学ぶ必要があります。配列は基本的にintegerまたはcharacterまたはanythingのセットです。文字値を配列に保存するときは、次のように定義します。

char array[] = {"somestringhere"};

ここで、そのような配列を別の配列に保存します。それは単純だ:

char* array1[];

array1は値を格納します。値はchar*タイプ、つまり文字配列のアドレスです。これらを他の配列に保存したい場合、

char** array2[];

これは、[配列のアドレス]の配列です。必要なのはそれだけです。

array1[0] = array; //same as: array1[0] = *array[0];
array2[0] = *array1[0];

これで、必要なものはすべて揃いました。あなたが核心に明確であることを願っています。 :)

6
user2279942

この例はturbo c ++ 1.01 dosで行われ、3.0 dosバージョンでも動作します。

char * text[] = {
  "message1",
  "message2",
  "message3"
};
3
steven tahner

あなたの例はポインタの配列を示していることに注意してください。配列の配列(多次元配列)が必要な場合は、配列定義ですべてのサイズを指定します。

char sentences[500][42]; /* sentences is an array of 500 elements.
                         ** each element is itself an array
                         ** capable of holding strings up to length 41 */
2
pmg

複数行のテキストを含む.cまたは.hファイルにテキストを保存する場合、char配列の配列の考え方に相当します。これを行うことができます:

char * text[] = {
  "message1",
  "message2",
  "message3"
};

char * text []、char near * text []、char far * text []、char huge * text []も使用できます。ポインタにはアスタリスクまたは星印が必要です。

forループを使用してテキストを表示できます。

char i; // int type can also be used
for (i = 0, i < 3; i++)
  printf("%s\n", text[i]);

他のループ:

char i = 0;  // may not be zero when declared as "char i;" only
while (i < 3) {
  printf("%s\n", text[i]);
  i++;
 }

または

char i = 0;  // may not be zero when declared as "char i;" only
do {
 printf("%s\n", text[i]);
 i++;
} while (i < 3);
1
steven tahner