Расширяя ответ @dbush:
Я думаю, что код все еще довольно хрупок.
#include <stdio.h>
#include <string.h>
int main() {
char src[40];
char src2[40];
char dest[20];
Здесь создается первая ловушка: dest меньше, чем оба источника.Хотя это может быть обработано, это требует гораздо большего усердия в последующем коде.Было бы лучше сделать место назначения всегда достаточно большим, чтобы вместить источник (и).
memset(dest, '\0', sizeof(dest)); //Good
Но также неплохо инициализировать другие массивы с 0.
memset(src, '\0', sizeof(src));
memset(src2, '\0', sizeof(src2));
Примечание: конечно, вы можете избежать проблем с memset, просто используя синтаксис инициализации массива:
char src[40] = {0};
char src2[40] = {0};
char dest[20] = {0};
Две следующие строки потенциально опасны при условии, что IRLдве строки могут не быть строковыми константами.(И даже тогда!) Проверка длины не предусмотрена ... Лучше:
// strcpy(src, "This is a string");
// strcpy(src2, "That");
strncpy(src, "This is a string", sizeof(src)- 1);
strncpy(src2, "That", sizeof(src2) -1);
Таким образом, мы гарантируем, что мы не вызовем переполнения.Мы также следим за тем, чтобы строки в src и src2 правильно заканчивались нулем.
Теперь копирование src / src2 в dest также опасно.Мы должны следить за тем, чтобы не переполнять dest.
//strncpy(dest, src, strlen(src));
//strncpy(dest, src2, strlen(src2));
Лучше:
strncpy(dest, src, sizeof(dest) - 1);
strncpy(dest, "That is a long rubbish string that easily could overflow dest", sizeof(dest) -1);
Мы копируем только столько, сколько dest может удержать и сохранить нулевой терминатор.
Сейчасна замену первых X символов.Опять же, мы должны убедиться, что переполнения не происходит.Мы используем strlen для определения фактического размера строки с нулевым символом в конце в src2, но нам нужно использовать / оценивать максимальный размер dest.Поэтому смесь strlen и sizeof.
memcpy просто для удовольствия.Вы также можете использовать strncpy.
memcpy(dest, src2, strlen(src2) < sizeof(dest) ? strlen(src2) : sizeof(dest));
printf("Final copied string : %s\n", dest);
}
Таким образом, вся безопасная реализация выглядит так:
#include <stdio.h>
#include <string.h>
int main() {
char src[40] = {0};
char src2[40] = {0};
char dest[20] = {0};
strncpy(src, "This is a string", sizeof(src)- 1);
strncpy(src2, "That is a long rubbish string and sooooooooooooooooooooooooo much more", sizeof(src2) -1);
strncpy(dest, src, sizeof(dest) - 1);
memcpy(dest, src2, strlen(src2) < sizeof(dest) ? strlen(src2) : sizeof(dest));
printf("Final copied string : %s\n", dest);
}
Обратите внимание, что при использовании sizeofтолько на первый взгляд эквивалентно strlen;на типах символов, которые работают, на других типах вам нужно сделать больше.