如何只初始化字符数组的一部分?
How to initialize only a slice of a character array?
我知道 C 的(非常简洁的)数组初始化语法,例如
char arr[12] = {[0] = '\n', [4] = 'z'};
初始化数组中的一些特定成员,但是有没有办法用字符串初始化整个数组块?像这样:
char filename[12] = {[0..9] = "data/img/"};
是否有允许它的内置语法?或者我必须坚持 memcpy():
char filename[strlen(basename) + 14];
memcpy(filename, "data/img/", 9);
memcpy(filename + 9, basename, l);
memcpy(filename + 9 + l, ".bmp", 4);
filename[l + 13] = '[=12=]';
是我目前拥有的; filename为相关字符数组,basename为可变字符串。
(通知所有反对者,此答案是在添加有关 VLA 信息的编辑前 18 分钟写的)
怎么了
char arr[12] = "string";
将初始化元素 0 .. 5 为 "string"
的字符,元素 6 使用终止 NUL 并将其余部分设置为也将其余部分设置为 NUL。
GCC 有一个扩展,其中您可以使用 单个 值初始化数组范围,即
char arr[12] = {[1 ... 7] = 'a'};
但它不适用于字符串。
初始化器根本不适用于可变长度数组。在这种情况下使用 sprintf
。
虽然这有效:
const char * basename = "base";
char filename[strlen(basename) + 14];
memcpy(filename, "data/img/", 9);
memcpy(filename + 9, basename, l);
memcpy(filename + 9 + l, ".bmp", 4);
filename[l + 13] = '[=10=]';
复杂且容易出错。
对于"strings"('[=12=]'
终止的char
数组)有str*()
函数族。
这样使用:
char filename[strlen(basename) + 14];
strcpy(filename, "data/img/"); /* Sets filename including the final 0. */
strcat(filename, basename); /* Appends to filename including the final 0. */
strcat(filename, ".bmp"); /* ditto */
如果你想使用变长数组,初始化是不可能的,但为什么不使用snprintf
而不是memcpy
链与手工计算的偏移量?
snprintf(filename, sizeof(filename), "data/img/%s.bmp", basename);
如果您不想手动计算 VLA 的维度,您可以使用空目标调用 snprintf
并让它为您计算结果字符串长度:
int len = snprintf(NULL, 0, "data/img/%s.bmp", basename);
char filename[len + 1];
(但请确保两次调用使用相同的格式字符串和参数。)
我知道 C 的(非常简洁的)数组初始化语法,例如
char arr[12] = {[0] = '\n', [4] = 'z'};
初始化数组中的一些特定成员,但是有没有办法用字符串初始化整个数组块?像这样:
char filename[12] = {[0..9] = "data/img/"};
是否有允许它的内置语法?或者我必须坚持 memcpy():
char filename[strlen(basename) + 14];
memcpy(filename, "data/img/", 9);
memcpy(filename + 9, basename, l);
memcpy(filename + 9 + l, ".bmp", 4);
filename[l + 13] = '[=12=]';
是我目前拥有的; filename为相关字符数组,basename为可变字符串。
(通知所有反对者,此答案是在添加有关 VLA 信息的编辑前 18 分钟写的)
怎么了
char arr[12] = "string";
将初始化元素 0 .. 5 为 "string"
的字符,元素 6 使用终止 NUL 并将其余部分设置为也将其余部分设置为 NUL。
GCC 有一个扩展,其中您可以使用 单个 值初始化数组范围,即
char arr[12] = {[1 ... 7] = 'a'};
但它不适用于字符串。
初始化器根本不适用于可变长度数组。在这种情况下使用 sprintf
。
虽然这有效:
const char * basename = "base";
char filename[strlen(basename) + 14];
memcpy(filename, "data/img/", 9);
memcpy(filename + 9, basename, l);
memcpy(filename + 9 + l, ".bmp", 4);
filename[l + 13] = '[=10=]';
复杂且容易出错。
对于"strings"('[=12=]'
终止的char
数组)有str*()
函数族。
这样使用:
char filename[strlen(basename) + 14];
strcpy(filename, "data/img/"); /* Sets filename including the final 0. */
strcat(filename, basename); /* Appends to filename including the final 0. */
strcat(filename, ".bmp"); /* ditto */
如果你想使用变长数组,初始化是不可能的,但为什么不使用snprintf
而不是memcpy
链与手工计算的偏移量?
snprintf(filename, sizeof(filename), "data/img/%s.bmp", basename);
如果您不想手动计算 VLA 的维度,您可以使用空目标调用 snprintf
并让它为您计算结果字符串长度:
int len = snprintf(NULL, 0, "data/img/%s.bmp", basename);
char filename[len + 1];
(但请确保两次调用使用相同的格式字符串和参数。)