C中结构内的字符串数组,无需分配
Posted
技术标签:
【中文标题】C中结构内的字符串数组,无需分配【英文标题】:array of strings within a struct in C without allocating 【发布时间】:2021-08-31 08:00:38 【问题描述】:我想用一个字符串数组初始化一个结构而不进行动态分配。可能吗? 我曾想过这样的事情,但它不起作用:
struct st_request
int GRID;
char NAME[15];
char (*PARAM)[15];
;
typedef struct st_request request;
request myrequest =
.GRID=1,
.NAME="GLOB",
.PARAM="RR1","RR3"
一个想法?感谢您的解决方案。
【问题讨论】:
PARAM 不是数组。它是一个指针。 试试[]
而不是[15]
@Ole 实现什么,得到一个编译器错误?
【参考方案1】:
有几种可能的变体,这里有两个:
struct s
char params1[32][64]; // 32 strings each with maximum length of 64 characters
///////////////////////////////////////////////////
char buffer[1024]; // byte buffer for individual strings
char* params2[32]; // 32 pointers you can let point
// to arbitrary positions into buffer
;
如果您不总是使用所有参数,您可能需要将 size_t numparams;
添加到上述两种解决方案中。
复制时,第一个变体很好,第二个变体你必须重新调整指针:
dest.params2[n] = dest.buffer + (source.params2[n] - source.buffer);
使用第二种变体,不要忘记为终止空指针留出空间。带有数据的结构可能如下所示:
buffer == "hello world\0hola mundo\0salut monde\0\0\0 ...";
// first parameter c a n be implicit: buffer
params2[0] == buffer + 12;
params2[1] == buffer + 23;
numParams == 3; // including the implicit parameter
或者,第一个参数可能总是指向缓冲区的开始,然后您可以一致地访问所有参数,而无需像 p = n == 0 ? buffer : params[n-1]
这样的任何特殊处理。
初始化可能如下所示:
struct s g_s =
.params1 =
"hello world",
"hola mundo",
"salut monde",
,
.buffer = "hello world\0hola mundo\0salut monde",
.params2 =
g_s.buffer + 12,
g_s.buffer + 23,
,
.numParams = 3,
;
不幸的是,您需要自己计算第二个变体的偏移量(您可能会编写一个帮助程序 script 为您执行此操作...)。
【讨论】:
感谢您的回答。 不知道能不能用 sizeof(g_s.params2) / sizeof(g_s.params2[0] 得到数组长度? @user2030243 当然可以,就像任何数组一样——当然,只要它还没有衰减为指针(例如,sizeof(g_s.params1)/sizeof(*g_s.params1)
用于另一个数组或sizeof(*g_s.params1)/sizeof(**g_s.params1)
用于子-数组)。但是,如果您想以这种方式替换 numParams
成员,那么您就不走运了除非所有这些参数都总是在使用中(sizeof-trick 为您提供总数可用容量,numParams
实际使用的插槽数)。【参考方案2】:
线
char (*PARAM)[15];
声明一个指针PARAM
,它指向一个char[15]
类型的数组,即指向一个有15个元素的数组,其中每个元素的类型为char
。
你可能想写
char *PARAM[15];
它声明了一个包含 15 个指针的数组,其中每个指针的类型为 char*
。与前面提到的指向整个数组的指针相比,这 15 个指针只指向一个字符。
在 C 中,处理字符串时,通常使用指向以空字符结尾的字符序列的第一个字符的指针。指向整个数组的指针通常只用在多维数组的上下文中,因为在多维数组中计算偏移量需要被引用对象的大小信息。
注意,变量名不能大写。这通常是为常量保留的。
另外,您的代码的最后一行缺少;
。
【讨论】:
char *PARAM[15]
确实与 OP 提供的初始化程序兼容,但我不太确定这是他们真正想要的。我认为 OP 的 NAME
和 *PARAMS
都以长度 15 声明可能很重要——也就是说,尽管他们写了“字符串数组”,但他们实际上的意思是“char
数组的数组”。但是,如果不是,那么如果他们打算按所示使用它,那么声明 const char *PARAM[15]
会更好。
char * PARAM[15] 可以工作(也可以使用 const)。谢谢。
不知能否用 sizeof(myRequest.PARAM) / sizeof(myRequest.PARAM[0] 得到数组长度?
@user2030243: 我不认为sizeof(myRequest.PARAM)
是你想要的,因为这会给你数组PARAM
的大小,即15 个指针的大小,即120 字节,假设每个指针有 8 个字节(64 位)。我也不认为sizeof(myRequest.PARAM[0])
是您想要的,因为它总是会给您单个指针的大小(8 个字节)。如果你想要字符串的实际长度,你必须使用strlen
。如果您想要指向的数组的实际大小,即可以存储的最大字符数,那么您必须通过其他方式记住这一点。
好的,我想我必须将初始化期间存储的字符串数量存储在其他地方(即两个:RR1 和 RR3)【参考方案3】:
您可以尝试以下方法:
#define PARAM_SIZE 20;
struct st_request
int GRID;
char NAME[15];
char PARAM[15*PARAM_SIZE];
;
request myrequest =
.GRID=1,
.NAME="GLOB"
strcpy (&myrequest.PARAM[0*PARAM_SIZE], "RR1");
strcpy (&myrequest.PARAM[1*PARAM_SIZE], "RR3");
【讨论】:
以上是关于C中结构内的字符串数组,无需分配的主要内容,如果未能解决你的问题,请参考以下文章