Я работаю над некоторым унаследованным кодом C (обычно я работаю в C #), и мне трудно с одним конкретным поведением строки.
Код, который мы имеем, выглядит примерно так:
int no = 0;
const char *values[1000];
for(int i = 0; i < num_of_values; i++) {
if (/*is invalid*/) continue;
values[no++] = list_of_objs[i]->value;
}
send_to_display(values, no);
, где list_of_objs[i]->value
- это const char *
, а само list_of_objs
объявлено как cpp_extern const struct obj_info list_of_objs[]
и заполнено статическими данными.На данный момент я считаю, что это строковые литералы, и они используются в другом месте кода как есть, поэтому я не могу изменить их начальные значения.
Мне поручено добавить динамический префикс вкаждая запись в массиве values
основана на другом значении.(Для простоты в приведенном ниже коде я просто показываю одно значение - я могу легко if
или ?:
для обработки нескольких случаев.) В C # это было бы тривиально с конкатенацией строк, но я знаю,Отношения Си со строками гораздо более ... сложные.
Моя наивная попытка состояла в том, чтобы объявить один буфер, sprintf
в нем, и затем добавить его в массив values
, но это дало мнесписок окончательного значения, повторяется i
раз.(Я понимаю, почему: повторное использование буфера означало, что каждый элемент в массиве был направлен на один и тот же буфер)
int no = 0;
const char *values[1000];
char buf[MAX_STRING_LENGTH];
for(int i = 0; i < num_of_values; i++) {
if (/*is invalid*/) continue;
sprintf(buf, "Value: %s", list_of_objs[i]->value);
values[no++] = buf;
}
send_to_display(values, no);
Я также пытался sprintf
напрямую в массив values
, но этовыдает мне предупреждение, которое должно быть ошибкой ( квалификатор const
отбрасывается ).
sprintf(values[no++], "Value: %s", list_of_objs[i]->value);
Я знаю, что мог бы объявить буфер в каждой итерациицикл и использовать его, но я беспокоюсь, что это приведет к утечке памяти.
Как я могу безопасно получить мою измененную строку в этот массив?