C中结构内的字符串数组,无需分配

array of strings within a struct in C without allocating

我想在不进行动态分配的情况下用字符串数组初始化一个结构。可能吗? 我曾想过这样的事情,但它不起作用:

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"}
}

一个想法?感谢您的解决方案。

有几种可能的变体,这里有两种:

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);

对于第二种变体,不要忘记留下 space 来终止空指针。带有数据的结构可能如下所示:

buffer     == "hello world[=12=]hola mundo[=12=]salut monde[=12=][=12=][=12=] ...";
// 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[=13=]hola mundo[=13=]salut monde",
        .params2 =
        {
                g_s.buffer + 12,
                g_s.buffer + 23,
        },

        .numParams = 3,

};

不幸的是,您需要自己计算第二个变体的偏移量(您可以编写一个帮助程序 脚本 为您完成...)。

char (*PARAM)[15];

声明了一个指针 PARAM,它指向一个类型为 char[15] 的数组,即指向一个包含 15 个元素的数组,其中每个元素的类型为 char.

你可能想写

char *PARAM[15];

其中声明了一个包含 15 个指针的数组,其中每个指针的类型为 char*。相对于前面提到的指向整个数组的指针,这15个指针只指向一个字符。

在C中,处理字符串时,通常使用指向空终止字符序列的第一个字符的指针。指向整个数组的指针通常只在多维数组的上下文中使用,因为需要引用对象的大小信息来计算多维数组中的偏移量。

注意变量名大写是不正常的。这通常保留给常量。

此外,您的代码的最后一行缺少 ;

您可以尝试以下方法:

#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");