如何初始化作为结构成员的字符串数组?

时间:2013-05-29 11:41:27

标签: c variables

如何“发送”字符串数组到结构?我的问题是,如何在代码中“拼写”。我收到错误,有大括号丢失。

我声明了一个带有字符串数组(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]

我知道这可能是一个菜鸟问题。对不起。

5 个答案:

答案 0 :(得分:2)

这是一种语言限制。

  

[C99: 6.7.8/13]:具有自动存储持续时间的结构或联合对象的初始化程序应该是如下所述的初始化程序列表,或者是具有兼容结构或联合类型的单个表达式。在后一种情况下,对象的初始值(包括未命名的成员)是表达式的初始值。

     

[C99: 6.7.8/14]:字符数组的数组可以用字符串文字初始化,可选择用大括号括起来。字符串文字的连续字符(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素。

     

[C99: 6.7.8/15]:元素类型与wchar_t兼容的数组可以用宽字符串文字初始化,可选择用大括号括起来。宽字符串文字的连续宽字符(如果有空间或数组大小未知,则包括终止空宽字符)初始化数组的元素。

     

[C99: 6.7.8/16]:否则,具有聚合或联合类型的对象的初始值设定项应该是元素或命名成员的大括号括起来的初始值设定项列表。

根本没有规则允许从另一个聚合的名称初始化聚合。

答案 1 :(得分: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;
}

答案 2 :(得分:1)

static char strs[30][50];

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

这将尝试将2d数组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
};

答案 3 :(得分:0)

这与如何初始化结构有关...

初始化列表中的项必须是常量表达式。字符串文字“foo”和“more foo”是这样的常量表达式。 strs不是常量表达式,因此在编译时无法识别其内容。因此,编译器不能在初始化列表中使用它。

来自C99

  

具有静态的对象的初始值设定项中的所有表达式   存储持续时间应为常量表达式或字符串文字。   ...

     

字符串数组可以由字符串文字初始化,可选       用括号括起来。字符串文字的连续字符(包括       如果有空间或数组的大小未知,则终止空字符)初始化数组的元素。

例如,你可以做到

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的{​​{1}}内容到编译器不会做的stringy1 ...你必须:)

更多crom c99 ...

  

...具有聚合或联合的对象的初始值设定项   type应该是一个括号括起来的元素的初始化列表或   命名成员......

因此char[]编辑初始化列表必须是char s括号内的列表。字符串文字初始化器只是很好的语法糖。

答案 4 :(得分:0)

如果这也是一个选项,您可以使用

memcpy(sample_settings.tstrs, strs, 1500);

在初始化块之外。