我尝试使用包含字符串的结构来编写程序:
typedef struct s_conf
{
char *shell1;
char *shell2;
char *shell3;
char *shell4;
char *server_ip;
} t_conf;
每行分析一个配置文本文件,我得到这些信息,并将其存储到变量中,如第1行和第4行。现在,我想为我的结构字段分配变量第1行和第4行的值:
char *line1 = "/var/www/host/current/app/console robot:file";
char *line4 = "192.168.00.00";
t_conf *conf;
if ((conf = malloc(sizeof(t_conf))) == NULL)
{
fprintf(stderr, "Malloc errorn");
return (-1);
}
strcpy(conf->shell1, line1);
strcpy(conf->server_ip, line4);
printf("line1 : '%s'n"; line1);
printf("line4 : '%s'n"; line4);
printf("t_conf->shell1 : '%s'n", conf->shell1);
printf("t_conf->server_ip : '%s'n", conf->server_ip);
输出:
line1 : '/var/www/host/current/app/console robot:file'
line4 : '192.168.00.00'
t_conf->shell1 : '/var/www/host/current/app'
t_conf->server_ip : '192.168.00.00'
如何正确分配字符串t_conf->shell1?我尝试了其他函数,如memcpy((、strdup((,并用malloc:t_conf->shell1 = malloc(strlen(line1) + 1)
分配变量,但它给了我相同的结果,我丢失了第1行的一部分?
我试着用这个包含字符串的结构写一个程序:
下面的struct s_conf
包含5个指针。它不包含任何字符串。对于C标准库,字符串是字符的数组,最多包含最后一个空字符(' '
(。为了让代码正常工作,需要这些数组的内存——在某个地方。
typedef struct s_conf {
char *shell1;
char *shell2;
char *shell3;
char *shell4;
char *server_ip;
} t_conf;
strcpy(conf->shell1, line1);
失败,因为conf->shell1
还没有指向副本可用内存的值。
用指向包含所需数据的内存的值填充这5个指针。
// allocate memory for the structure
conf = malloc(sizeof *conf);
assert(conf);
// Simply copy the pointer if `line1` will exist for as long as `conf`.
conf->shell1 = line1;
// or
// Create an allocated copy.
conf->shell1 = strdup(line1);
// With this method, be sure to free the memory before freeing conf
...
free(conf->shell1);
free(conf);
strdup()
不是一个标准的库函数,但非常常见。如果需要,制作一个等效的。示例:(根据您的需求量身定制(
char *my_strdup(const char *s) {
if (s) {
size_t sz = strlen(s) + 1;
char *dest = malloc(sz);
if (dest) {
return memcpy(dest, src, sz);
}
}
return NULL;
}
strcpy(conf->shell1, line1);
您需要空间来存储line1
此外(正如@cat在评论中指出的(strcpy
是危险的,必须在生产代码中避免,另一种选择是strdup
(非标准(或snprintf
:
size_t size = strlen(line1) + 1;
conf->shell1 = malloc(size);
snprintf(conf->shell1, size, "%s", line1);
当不再需要该空间时,应使用free(conf->shell1);
返回该空间。
与conf->server_ip
相同
请注意,如果您不需要修改这些字符串,则不需要复制,只需分配:
conf->shell1 = line1;