2

我知道 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] = '\0';

是我目前拥有的;filename是被指控的字符数组,而basename是一个变量字符串。

4

3 回答 3

4

(请注意所有反对者,此答案是在添加有关 VLA 信息的编辑前18分钟写的)

有什么问题

char arr[12] = "string";

这将使用字符 of初始化元素0 .. 5"string" ,使用终止 NUL 初始化元素6,并将其余部分也设置为 NUL。

GCC 有一个扩展,您可以在其中使用单个值初始化数组的范围,即

char arr[12] = {[1 ... 7] = 'a'};

但它不适用于字符串。


初始化程序根本不适用于可变长度数组。在这种情况下使用sprintf

于 2018-01-02T10:10:34.483 回答
4

如果你想使用可变长度数组,初始化是不可能的,但为什么不使用手动计算偏移量snprintf的链呢?memcpy

snprintf(filename, sizeof(filename), "data/img/%s.bmp", basename);

如果您不想手动计算 VLA 的尺寸,您可以snprintf使用 null 目标调用并让它为您计算结果字符串长度:

int len = snprintf(NULL, 0, "data/img/%s.bmp", basename);
char filename[len + 1];

(但请确保您对两个调用使用相同的格式字符串和参数。)

于 2018-01-02T10:45:39.657 回答
1

虽然这有效:

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] = '\0';

这很复杂且容易出错。

对于“字符串”('\0'-terminated char-arrays),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 */
于 2018-01-02T10:44:14.517 回答