Как инициализировать только часть массива символов?

Я знаю о синтаксисе инициализации массива 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 - переменная строка.

3 ответа

Решение

Если вы хотите использовать массивы переменной длины, об инициализации не может быть и речи, но почему бы не использовать 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];

(Но убедитесь, что вы используете одинаковую строку формата и аргументы для обоих вызовов.)

(Обратите внимание на всех downvoters, этот ответ был написан за 18 минут до редактирования, который добавил информацию о VLA)

Что случилось с

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

Это сложно и подвержено ошибкам.

Для "струн" ('\0'-завершённый 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 */
Другие вопросы по тегам