繁体   English   中英

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

[英]How can I initialise an array of strings that is a member of a struct?

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

我用字符串数组(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]

我知道这可能是一个菜鸟问题。 抱歉

这是语言限制。

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

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

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

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

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

选项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;
}
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
};

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

初始化程序列表中的项目必须是常量表达式。 字符串文字“ 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[]进行编辑,初始化程序列表必须是大括号括起来的char列表。 字符串文字初始化程序只是很好的语法糖。

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

memcpy(sample_settings.tstrs, strs, 1500);

在初始化块之外。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM