質問 |
||
| QNo.3979877 | 引数として二次元配列を利用する方法について(C言語) | |
|---|---|---|
| 質問者:vtr9 |
#define PR_SIZE 40 char hp[PR_SIZE][3]; char *initial; initial = "aa,aa"; GetPrivateProfileString("Setting", "hp", initial, strText, 1024, ini_path); initial = strtok(strText, ","); for(i = 0; i < PR_SIZE; i++) strcpy(hp[i], "\0"); for(i = 0; initial != NULL && i < PR_SIZE; i++){ strcpy(hp[i], initial); initial = strtok(NULL, ","); } という部分を関数化しようとして、 ReadIni_pr(&(pr.hp[0][3]), "hp", "aa,aa"); //関数呼び出し void ReadIni_pr(char *a[], const char* str, char* initial){ char strText[128]; GetPrivateProfileString("Setting", str, initial, strText, 1024, ini_path); for(int i = 0; i < PR_SIZE; i++) strcpy(a[i], "\0"); initial = strtok(strText, ","); for(int i = 0; initial != NULL && i < PR_SIZE; i++){ strcpy(a[i], initial); initial = strtok(NULL, ","); } } と書いてみたのですが、第一引数の処理がどうしても上手くいきません できるだけ関数の内部を変更しない形で、上手くいく方法はないでしょうか (インクルードに関しては省略してあります) あと、char sp[PR_SIZE][5];に関しても同様の関数で処理したいのですが、可能でしょうか? |
|
困り度:
|
||
| 質問投稿日時: 08/04/27 14:59 |
||
回答良回答20pt |
|
| ANo.3 | 現行の > char hp[PR_SIZE][3]; を当該関数に渡す場合は、 > void ReadIni_pr(char *a[], const char* str, char* initial){ を void ReadIni_pr(char (*a)[3], const char* str, char* initial){ とすればよいと思います。第一引数の意味は、 「aは、要素数3の配列へのポインタ」です。 こうすれば、呼び出し時の > ReadIni_pr(&(pr.hp[0][3]), "hp", "aa,aa"); は ReadIni_pr(pr.hp, "hp", "aa,aa"); でよいと思います。 なお、 > char sp[PR_SIZE][5];に関しても同様の関数で処理したい のであれば、可能ならば当該配列の定義を char hp[3][PR_SIZE]; や char sp[5][PR_SIZE]; と変更して、当該関数を void ReadIni_pr(char (*a)[PR_SIZE], const char* str, char* initial){ とすれば、当該配列の第一要素数がいくつであっても対応できます。 |
|---|---|
| 回答者:asuncion | |
| 種類:アドバイス どんな人:一般人 自信:参考意見 |
|
| 回答日時: 08/04/27 17:31 |
|
| |
| この回答への補足 | 一応、C++も扱える状況なので、引数だけを代えて同名で別の関数を作っておくことで回避してみます ありがとうございました |
| この回答へのお礼 | なるほど。その場所を括弧で囲むという考えが出てきませんでした。 a[][3]をポインタへ変形させたという捉え方でしょうか。 a[][3] → (a[])[3] → (*a)[3] といった具合に。 (真ん中はソースとしては変ですが…) sp[PR_SIZE][5]に関しては、文字列なので逆転させると別の箇所での扱いが不便になるため、別の関数を使ってみます。 仮に*a[3]としたときには、a[3][]の方でしょうか。 これだと関数の引数としては不適格ではありますが。 |
回答 |
|
| ANo.2 | >ReadIni_pr(&(pr.hp[0][3]), "hp", "aa,aa"); //関数呼び出し あ、宣言細かく見てませんでした。 pr.hp[0][2]ですよね? |
|---|---|
| 回答者:bushclean | |
| 種類:アドバイス どんな人:一般人 自信:参考意見 |
|
| 回答日時: 08/04/27 15:37 |
|
| |
| この回答への補足 | ReadIni_pr(&(pr.hp[0][3]), "hp", "aa,aa"); //関数呼び出し すいません、元々構造体だったものを簡略のために省いていたのですが、消し忘れてしまっていました。 ReadIni_pr(&hp[0][3], "hp", "aa,aa"); //関数呼び出し と解釈してください。 ちなみにこの &hp[0][3] の部分なのですが、暫定的にこういった状態になっているだけであって、例えば、 hp、hp[3]、&hp[0][0] などとしても上手く動作しません(型の合わないものも含まれますが、そのレベルも含めて動作云々というよりもコンパイルのレベルでの問題でもあります) さらに関数内にあるstrcpy(a[i], "\0");の部分に関して上手く動作するようにしたい(ここを動作させることが目的です)ので、できればこれを主眼において引数を考えていただけるとありがたいです。 引数を…というのは、関数の呼び出しも勿論ですが、関数の宣言内の方も考慮して下さい。 |
| この回答へのお礼 | この回答にお礼をつける(質問者のみ) |
回答 |
|
| ANo.1 | >ReadIni_pr(&(pr.hp[0][3]), "hp", "aa,aa"); //関数呼び出し これ、pr.hp[0][3] という、一つの値への参照だけしか渡してませんよ。 変数の最後の値を渡しているので、関数内で変数サイズを超えて 書き換えが起こっているのでしょう。 >あと、char sp[PR_SIZE][5];に関しても同様の関数で処理したいのですが、可能でしょうか? という課題も含めて配列の二次元目の大きさも関数の引数に入れれば よいでしょう。 (えーと、「ReadIni_pr(char *a[], ...」で受け取って良いかどうかはパスしておきます(汗 私もその程度のレベルなので) |
|---|---|
| 回答者:bushclean | |
| 種類:回答 どんな人:一般人 自信:参考意見 |
|
| 回答日時: 08/04/27 15:35 |
|
| |
| この回答へのお礼 | この回答にお礼をつける(質問者のみ) |