Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

構造体の多次元配列を初期化するには

3,754 views
Skip to first unread message

歩野零一

unread,
Feb 10, 2000, 3:00:00 AM2/10/00
to
ポインタでも結構ですから、ご存知の方がいらっしゃいましたら
ご教授願えれば幸いです。

構造体を定義した後、初期化するソースをコンパイルすると、次の
ようなエラーが出ます。(ソースは下記参照願います)
test2.c:11: warning: excess elements in array initializer after `test'
中略
test2.c:25: warning: excess elements in array initializer after `test'
この構造体の配列の初期化は1次元では問題ないのですが、2次元
だとなぜか上手くいきません。
配列じゃないから上手くいかないのか、とか配列にしてstring[128]
などと変えてみたもののさっぱりです。このような配列をmallocを
使わずに上手く初期化する手はないものでしょうか。
使用したコンパイラはgcc2.91.60(egcs-1.1.1 release)です。

#include <stdio.h>

typedef struct {
int length;
char *string;
} LASCII;

static const LASCII test[2][8]={
{7, "abcdefg"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},

{7, "abcdefg"},
{7, "hijklmn"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"}
};

main()
{
int i, j;

for(i = 0;i < 2; i++){
for(j = 0;j < 8; j++){
printf("%s\n", test[i][j].string);
}
}
}


歩野零一

unread,
Feb 10, 2000, 3:00:00 AM2/10/00
to
自己レスです。
http://www.catnet.ne.jp/kouno/c_faq/c2.html#0

こちらによると、あまり良いやり方ではないようですね。
しかし、1次元はOKなのに2次元がダメなのは惜しいです。


OKINO Kouji

unread,
Feb 10, 2000, 3:00:00 AM2/10/00
to

としてみては?
--
// 沖野 幸治 OKINO Kouji
// 株式会社コア 北海道カンパニー
// E-mail: ok...@core.co.jp

Shinobu Kumaoka

unread,
Feb 10, 2000, 3:00:00 AM2/10/00
to
歩野零一 wrote:

> static const LASCII test[2][8]={
> {7, "abcdefg"},
> {0, "\0"},
> {0, "\0"},
> {0, "\0"},
> {0, "\0"},
> {0, "\0"},
> {0, "\0"},
> {0, "\0"},
>

これでいいのでは?
あと、"\0"ってなにか意味があるのでしょうか?
単に、""でいいような気がするのですが。
--
cog...@sp.hudson.co.jp
株式会社ハドソン 第3開発部
熊岡 忍(Kumaoka Shinobu)

c.g.green

unread,
Feb 10, 2000, 3:00:00 AM2/10/00
to
河原@日本LSIカード(株)です。

歩野零一さん、こんにちは。

> ポインタでも結構ですから、ご存知の方がいらっしゃいましたら
> ご教授願えれば幸いです。

以下のようにすれば良いと思います、しかし、私が組むときはlengthはまず
LASCII構造体から削除します。文字列の長さの情報はstringが持っているのでlength
は冗長なデータだからです(^○^)。この例では文字列の長さは明らかですが、長くな
るととたんに効率も悪くなりミスも多発します。多バイト長コードでは文字数を読み
取る事は不可能です、半角カナと全角カナの差もFONTによっては見分けが付きません
ましてESCシーケンス等が入ればもうお手上げですし(^○^)。

typedef struct {
int length;
char *string;
} LASCII;

static LASCII test[2][8]={
{
{0, "abcdefg"},


{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
},
{

{0, "abcdefg"},
{0, "hijklmn"}


{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
}

};

int main(int argc, char* argv[])
{
int i, j;

/* 初期化 */


for(i = 0;i < 2; i++){
for(j = 0;j < 8; j++){

if (test[i][j].string)
test[i][j].length = strlen(test[i][j].string); /* 文字の長さの設
定は実行時にする、人が数える事によって起きるエラーをふせく */
}
}

/* 使用 */


for(i = 0;i < 2; i++){
for(j = 0;j < 8; j++){

if (test[i][j].string == NULL)
printf("\n");
else


printf("%s\n", test[i][j].string);
}
}

return 0;
}

Yoshio Kiya

unread,
Feb 10, 2000, 3:00:00 AM2/10/00
to
 c.g.greenさん、こんにちは、木屋です。

c.g.green wrote in <87tr7a$e11$1...@newsflood.osaka.att.ne.jp>


> 以下のようにすれば良いと思います、しかし、私が組むときはlengthはまず
> LASCII構造体から削除します。文字列の長さの情報はstringが持っているのでlength
> は冗長なデータだからです(^○^)。この例では文字列の長さは明らかですが、長くな
> るととたんに効率も悪くなりミスも多発します。

 文字数としては意味が無くてもデーターバイト数としては意味あ
りますよね。

 文字列の複写時になんかに、あらかじめ長さが解っているとかな
り速度を稼ぐことが出来るんで、私はこういった形のデーターを時
々使います。

#define dfs(s) { sizeof(s)-1, s }
static const LASCII test[2][2] =
{
{
{ dfs("abcdefg"), dfs(""), },
},
{
{ dfs("abcdefg"), dfs("hijklmn"), },
};
};
#undef dfs

 なんてやると自動でバイト数を設定してくれます。

=== Nihon Application Co.,LTD. 木屋 善夫 ki...@nac.co.jp ===

歩野零一

unread,
Feb 10, 2000, 3:00:00 AM2/10/00
to
熊岡さま、沖野さま、河原さま、木屋さま、ご回答ありがとうござい
ます。問題は解決しました。

問題は'{}'が足りなかったため起きたようです。

Yoshio Kiya wrote:
>文字列の複写時になんかに、あらかじめ長さが解っているとかな
>り速度を稼ぐことが出来るんで、私はこういった形のデーターを時

ビンゴ、仰る通りです。諸事情により、libc等のライブラリ関数を
極力使わない、かつ文字列を長さを一旦調べたら、2度と調べ直さない
のをポリシーとしてプログラムを開発しておりました。

先のサンプルの実体はHTTPのレスポンスメッセージです。

木屋様の書き方はスマートですね。勉強になりました。


Takao Ono

unread,
Feb 10, 2000, 3:00:00 AM2/10/00
to
小野@名古屋大学 です.

<38A258A9...@mail.goo.ne.jp>の記事において
_teku...@mail.goo.ne.jpさんは書きました。
_tekuno01> static const LASCII test[2][8]={
{
_tekuno01> {7, "abcdefg"},
....
_tekuno01> {0, "\0"},
}, {
_tekuno01> {7, "abcdefg"},
....
_tekuno01> {0, "\0"}
}
_tekuno01> };

のように {, } を追加してください.
# 配列の各次元に対して {, } が必要です. 組み込み型でも同じじゃな
# いですか?
--
名古屋大学 工学部 電子工学科 平田研究室
小野 孝男

fu...@kiss.taihaku.sendai.jp

unread,
Feb 11, 2000, 3:00:00 AM2/11/00
to
藤森です。
# デイジー?

>> On Thu, 10 Feb 2000 15:20:25 +0900, 歩野零一 <_teku...@mail.goo.ne.jp> said:

tekuno01> 構造体を定義した後、初期化するソースをコンパイルすると、次の
tekuno01> ようなエラーが出ます。(ソースは下記参照願います)
tekuno01> test2.c:11: warning: excess elements in array initializer after `test'
tekuno01> 中略
tekuno01> test2.c:25: warning: excess elements in array initializer after `test'

はい、構文を間違えています。

static const LASCII test[2][8]={
{

{7, "abcdefg"},


{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"}
},

{
{7, "abcdefg"},
{7, "hijklmn"},


{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"},
{0, "\0"}
}

};

ですよ。


Yoshio Kiya

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to
 自己フォローです。

 うぎゃ (^_^; {}, が 1ネスト多いです。m(_ _)m

#define dfs(s) { sizeof(s)-1, s }
static const LASCII test[2][2] =
{
{ dfs("abcdefg"), dfs(""), },

{ dfs("abcdefg"), dfs("hijklmn"), },
};
#undef dfs

 が、正解でした。

c.g.green

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to
河原@日本LSIカード(株)です。

歩野零一さん、こんにちは。

> ビンゴ、仰る通りです。諸事情により、libc等のライブラリ関数を
> 極力使わない、かつ文字列を長さを一旦調べたら、2度と調べ直さない
> のをポリシーとしてプログラムを開発しておりました。
>

> 木屋様の書き方はスマートですね。勉強になりました。

なるほど(^○^)、木屋さんのマクロを参考にケアレスミスのないプログラムを作
成してください(^○^)。

わたしはいま、他人の作成したデーターの多重!!冗長定義(^_^;)に悩んでいたも
ので(^○^)ハハハ、ついつい。

c.g.green

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to
河原@日本LSIカード(株)です。

木屋さん、こんにちは。

>  うぎゃ (^_^; {}, が 1ネスト多いです。m(_ _)m

> static const LASCII test[2][2] =
> {
> { dfs("abcdefg"), dfs(""), },
> { dfs("abcdefg"), dfs("hijklmn"), },
> };
> #undef dfs

(^○^)ふふふふ、','コンマも一つ多いのでは(^_^;)。

歩野零一

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to
いえ、気付いていましたが、私が直せば済むことでしたし、多分
ご本人もご承知だろうと思ったのでわざわざ指摘はしませんでした。

皆様ありがとうございました。

OKINO Kouji

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to
"c.g.green" wrote:
>
> 河原@日本LSIカード(株)です。
>
> 木屋さん、こんにちは。
>
> >  うぎゃ (^_^; {}, が 1ネスト多いです。m(_ _)m
> > static const LASCII test[2][2] =
> > {
> > { dfs("abcdefg"), dfs(""), },
> > { dfs("abcdefg"), dfs("hijklmn"), },
> > };
> > #undef dfs
>
> (^○^)ふふふふ、','コンマも一つ多いのでは(^_^;)。

文法上は初期値式リストの最後に','があっても問題はないです。

#私はどっちかというと将来の追加を見込んで、
#最後にも','をつけるようにしてます。

Hideo Sir MaNMOS Morishita

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to

"c.g.green" <cg_...@osa.att.ne.jp> writes:

> 河原@日本LSIカード(株)です。
>
> 木屋さん、こんにちは。
>
> >  うぎゃ (^_^; {}, が 1ネスト多いです。m(_ _)m
> > static const LASCII test[2][2] =
> > {
> > { dfs("abcdefg"), dfs(""), },
> > { dfs("abcdefg"), dfs("hijklmn"), },
> > };
> > #undef dfs
>
> (^○^)ふふふふ、','コンマも一つ多いのでは(^_^;)。

いいえ、むしろ、ソースの変更を考えるならつけている方が良いです。


--
___ わしは、山吹色のかすてーらが大好きでのぅ
[[o o]] ふぉっふぉっふぉ
'J' 森下 お代官様 MaNMOS 英夫@ステラクラフト
PGP Finger = CD EA D5 A8 AD B2 FE 7D 02 74 87 52 7C B7 39 37

c.g.green

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to
河原@日本LSIカード(株)です。

沖野さん、みなさん、こんにちは。

> 文法上は初期値式リストの最後に','があっても問題はないです。
>
> #私はどっちかというと将来の追加を見込んで、
> #最後にも','をつけるようにしてます。

おおおお、そうなのか(^_^;)、これは大変失礼しました(;;;^_^;;;)赤面。
test[][2]になっているとtest[3][2]になるけどtest[2][2]なら問題無しという
ことですね(^○^)。

OKINO Kouji

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to

手元に確認できる資料がないので規格上はどうなってるのかわかりませんが
VC++5.0では、test[][2]でもtest[2][2]でもsizeof(test)は同じになりましたの

少なくともVC++5.0ではtest[3][2]にはならないようです。

Kazuo Fox Dohzono

unread,
Feb 14, 2000, 3:00:00 AM2/14/00
to
堂園です.

In article <squk8k8qp...@stellar.co.jp>


man...@stellar.co.jp (Hideo "Sir MaNMOS" Morishita) writes:

> > > static const LASCII test[2][2] =
> > > {
> > > { dfs("abcdefg"), dfs(""), },
> > > { dfs("abcdefg"), dfs("hijklmn"), },
> > > };
> > > #undef dfs
> >
> > (^○^)ふふふふ、','コンマも一つ多いのでは(^_^;)。
>
> いいえ、むしろ、ソースの変更を考えるならつけている方が良いです。

“C プログラミングの落とし穴”にもそういう話があって納得したものですが,
列挙型の最後に `,' が許されていないのは何故なんでしょうね (初期化だか
らこそ許されている?).

いくつかのコンパイラはそのまま通しちゃうんですが, いつだったか
pedantic なコンパイラに怒られてから私はエラー予防の為に

typedef enum _misc_stat_t {
e_misc_attach,
e_misc_open,
...;
e_misc_close,
e_misc_detach,
E_MISC_N
} misc_stat_t

などとしています (結構 E_MISC_N を参照するケースもありますし).

# ただ, これをやると今度は E_MISC_N が switch で漏れてるという警告が….

--
Kazuo Fox Dohzono / doh...@hf.rim.or.jp

[12],(6,9),0,0,2

c.g.green

unread,
Feb 15, 2000, 3:00:00 AM2/15/00
to
河原@日本LSIカード(株)です。

沖野さん、みなさん、こんにちは。

> 手元に確認できる資料がないので規格上はどうなってるのかわかりませんが


> VC++5.0では、test[][2]でもtest[2][2]でもsizeof(test)は同じになりましたの
> で
> 少なくともVC++5.0ではtest[3][2]にはならないようです。

えええええ(^_^;)、そうだったのか、VC++6.0でも確認いたしました(^_^;)。長
いこと勘違いしておりました(^○^)。ワーニングをレベル4にしても何も出てきませ
んね、char test[2] = { 1, 2, }としてもやはり何も出ません。僕としてはこれは
ワーニング出してほしいけどな(^_-)。なんでやろ(?o?)。

Yoshio Kiya

unread,
Feb 15, 2000, 3:00:00 AM2/15/00
to
 河原さん、こんにちは、木屋です。

c.g.green wrote in <88a8de$b73$1...@newsflood.osaka.att.ne.jp>
> 僕としてはこれはワーニング出してほしいけどな(^_-)。なんで
> やろ(?o?)。

 たぶん、C言語の仕様出そう決まってるからじゃないでしょうか?

=== Nihon Application Co.,LTD. 木屋 善夫 ki...@nac.co.jp ===

# 用語の間違いが無いか良く確認しなきゃ(^_^; fj.* は苦手です。

Tomohiko Sakamoto

unread,
Feb 16, 2000, 3:00:00 AM2/16/00
to
In article <38A2B72C...@mail.goo.ne.jp>,
歩野零一 <_teku...@mail.goo.ne.jp> writes:
> 問題は'{}'が足りなかったため起きたようです。

逆に、{ } を取ってしまうという手もあります。お薦めはしませんが。

static const LASCII test[2][8] = {

7, "abcdefg", 0, "", 0, "", 0, "", 0, "", 0, "", 0, "", 0, "",
7, "abcdefg", 7, "hijklmn", 0, "", 0, "", 0, "", 0, "", 0, "", 0, ""
};

--
坂本智彦 saka...@sm.sony.co.jp

0 new messages