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

这是语言限制。

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

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

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

[C99: 6.7.8/16]:否则,具有聚合或联合类型的对象的初始化程序应为元素或命名成员的初始化程序的大括号括起来的列表。

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

于 2013-05-29T12:00:34.383 回答
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
};

这将尝试将 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
};
于 2013-05-29T11:58:30.043 回答
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的内容......你必须:)stringy2stringy1

更多 crom c99...

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

因此,char[]初始化列表的编辑必须是一个大括号括起来的chars 列表。字符串文字初始化器只是很好的语法糖。

于 2013-05-29T11:58:38.273 回答
0

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

memcpy(sample_settings.tstrs, strs, 1500);

在初始化块之外。

于 2013-05-29T12:07:55.127 回答