Это утомительная проблема управления памятью и обработки строк в Си.Если я прав, думая, что для n входных строк вам нужно n выходных строк, каждая длиннее последней, я бы сделал это:
char **results = malloc(num * sizeof(char*));
if (results == 0) return ENOMEM;
int lastlen = 0;
for (int i = 0; i < num; ++i) {
char *newresult = malloc(lastlen + strlen(str[i]) + 4);
if (newresult == 0) { /* even more tedious freeing code goes here */ }
results[i] = newresult;
char *ptr = newresult;
if (i != 0) {
ptr += sprintf(ptr, "%s:", results[i-1])
}
sprintf(ptr, "[%s]", str[i])
lastlen = strlen(newresult);
}
или что-то в этом роде.Очевидно, что здесь есть хорошая возможность написать более одной функции, чтобы отделить генерацию этих строк от хранения их в массивах.Есть также обычный аргумент, что мы можем добиться большего успеха в ставках риска переполнения буфера, чем sprintf
+ умственная арифметика.
Правка: украл использование sprintf
у Оскара.1009 * Другое редактирование: пример с asprintf
, который доступен в GNU и BSD.Это включает в себя утомительный код освобождения, путь успеха на самом деле довольно хорош.Возвращает вновь выделенный массив при успехе, 0 при ошибке.Предполагается, что вызывающая сторона знает num
и, следовательно, знает, как долго будет длиться массив: если это бесполезно, массив может заканчиваться нулем.
char **results = malloc(num * sizeof(char*));
if (results != 0) {
const char *last = "";
const char *sep = "";
for (int i = 0; i < num; ++i) {
if (asprintf(results + i, "%s%s[%s]", last, sep, str[i]) == -1) break;
last = str[i];
sep = ":";
}
if (i == num) return results; // success!
// asprintf failed, so the value of results[i] is undefined
while (i != 0) free(results[--i]);
free(results);
}
return 0;