Reputation: 47
I want to initialize a structure with an array of string without doing dynamic allocation. Is it possible? I had thought of something like this but it doesn't work:
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"}
}
An idea? Thanks for your solutions.
Upvotes: 0
Views: 163
Reputation: 25516
There are several variants possible, here two of them:
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
};
If you don't always use all parameters you might want to add size_t numparams;
to any of both of above solutions.
When copying, first variant is just fine, with second variant you will have to re-adjust the pointers:
dest.params2[n] = dest.buffer + (source.params2[n] - source.buffer);
With second variant, don't forget to leave space for terminating null pointers. A struct with data might then look like this:
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
Alternatively first parameter might always point to buffer's begin, then you can access all parameters consistently without any special handling like p = n == 0 ? buffer : params[n-1]
.
Initialisation can look like this:
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,
};
Unfortunately you need to count the offsets for second variant on your own (you might write a helper script doing that for you...).
Upvotes: 2
Reputation: 24726
The line
char (*PARAM)[15];
declares a single pointer PARAM
which points to an array of type char[15]
, i.e. to an array of 15 elements, in which each element has the type char
.
You probably want to write
char *PARAM[15];
which declares an array of 15 pointers, in which each pointer has the type char*
. In contrast to the pointer mentioned earlier, which points to an entire array, these 15 pointers only point to a single character.
In C, when handling strings, it is normal to use pointers to the first character of a null-terminated character sequence. Pointers to entire arrays are normally only used in the context of multi-dimensional arrays, because the size information of the referenced object is needed to calculate the offset in a multi-dimensional array.
Note that it is not normal to write the names of variables in upper-case. This is normally reserved for constants.
Also, there is a ;
missing in the last line of your code.
Upvotes: 1
Reputation: 11209
You could try the following:
#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");
Upvotes: 0