2

文字列の配列を構造体に「送信」するにはどうすればよいですか? 私の質問は、コードでどのように「スペル」するかです。中括弧がないというエラーが表示されます。

文字列の配列 (tstrs) を持つ構造体を宣言しました。

typedef struct
{
    bool dummy;
    char *tdata1;
    char *tdata2;
    char tstrs[30][50];
} SampleSettings;

main.c からこの構造体にデータを渡すと、このコードを使用すると機能します

static char strs[30][50];

SampleSettings sample_settings  = {
    false,"nothing","empty",{"foo","morefoo"}
};

しかし、たとえばこのコードを使用すると

static char strs[30][50];

SampleSettings sample_settings  = {
    false,"nothing","empty",strs
};

コンパイラは停止します

エラー: イニシャライザを囲む括弧がありません [-Werror=missing-braces]

これが初歩的な質問になる可能性があることは承知しています。そのために残念。

4

5 に答える 5

2

オプション1

typedef struct
{
    bool dummy;
    char *tdata1;
    char *tdata2;
    char tstrs[30][50];
} SampleSettings;

int main()
{
    SampleSettings sample_settings  = {
        false,"nothing","empty",{"foo","morefoo"}
    };

    return 0;
}

オプション 2

構造体を変更したことを確認する

typedef struct
{
    bool dummy;
    char *tdata1;
    char *tdata2;
    char **tstrs;
} SampleSettings;

int main()
{
    char strs[30][50] = {{0}};
    SampleSettings sample_settings  = {
        false,"nothing","empty",(char **)strs
    };
    return 0;
}
于 2013-05-29T12:04:23.477 に答える
1
static char strs[30][50];

SampleSettings sample_settings  = {
    false,"nothing","empty",strs
};

これは、2 次元配列の最初の要素を に初期化しようとしstrs[0][0]ますstrs

strs[0][0] = (char) strs;

(gcc 4.7.2, -Wall)で確認できるように

a.c:15:1: warning: initialization makes integer from pointer without a cast [enabled by default]
a.c:15:1: warning: (near initialization for ‘sample_settings.tstrs[0][0]’) [enabled by default]

しかし、とにかく動作しません

a.c:19:1: error: initializer element is not constant
a.c:19:1: error: (near initialization for ‘sample_settings.tstrs[0][0]’)

値をマクロ定義できます

#define STRS  { "foo", "morefoo" }
SampleSettings sample_settings  = {
    false,"nothing","empty", STRS
};
于 2013-05-29T11:58:30.043 に答える
0

これは、構造を初期化する方法に関係しています...

初期化子リストの項目は定数式でなければなりません。文字列リテラル "foo" と "more foo" は、そのような定数式です。strsは定数式ではないため、コンパイル時にその内容を知ることはできません。したがって、コンパイラは初期化リストでそれを使用できません。

C99から

静的記憶域期間を持つオブジェクトの初期化子のすべての式は、定数式または文字列リテラルでなければなりません。...

文字型の配列は、文字列リテラルで初期化することができ、オプションで中括弧で囲みます。文字列リテラルの連続する文字 (空きがある場合、または配列のサイズが不明な場合は、終端の null 文字を含む) は、配列の要素を初期化します。

たとえば、次のことができます。

char stringy[10] =  "a string";

これはと同等です

char stringy[10] = { 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', '\0' };

あなたはできません

char stringy1[10] = "string 1";
char stringy2[10] = stringy1;

これはstringy1、配列の最初のバイトのアドレスに解決されるためです。ここでは、アドレス (char *ポインター) で配列を初期化しようとしています。Cはこれを行うことができません...これには、コンパイラが実行しないmemcpyコンテンツが含まstringy2れます...あなたがしなければなりません:)stringy1

もっとクロムc99...

...集約型または共用体型を持つオブジェクトの初期化子は、要素または名前付きメンバーの初期化子の中括弧で囲まれたリストでなければなりません...

したがって、初期化子リストの編集はchar[]、中括弧で囲まれた s のリストでなければなりませんchar。文字列リテラルの初期化子は、ちょうどよい構文糖衣です。

于 2013-05-29T11:58:38.273 に答える