strncpy()
не делает то, о чем вы, вероятно, думаете.
strncat()
- это «более безопасная» версия strcat()
, позволяющая указать размер целевого массива.
strncpy()
- это , а не соответствующая "более безопасная" версия strcpy()
. Если целевой массив слишком большой, strncpy()
заполнит его нулевыми символами; В 99% случаев это не нужно, так как вам нужен только один '\0'
, чтобы отметить конец строки. Хуже того, если целевой массив слишком мал, strncpy()
скопирует столько символов, сколько может , и оставит цель без определения .
strncpy()
был разработан для неясной структуры данных, используемой ранними системами Unix для хранения имен файлов. Имя файла было сохранено в 14-байтовом буфере фиксированной длины, дополненном нулевыми байтами. Если бы имя файла было ровно 14 символов, не было бы нулевого терминатора. Это не строка .
В маловероятном случае, когда вам нужна такая структура данных, тогда strncpy()
- это просто вещь. В противном случае не используйте его; просто используйте strcpy()
после подтверждения того, что цель достаточно большая.
Вот как я мог бы написать эту функцию:
void function(char *a, char *b)
{
char newStr[100];
/* Make newStr an empty string so you can concatenate onto it */
newStr[0] = '\0';
strncat(newStr, a, sizeof newStr - 1); /* edited */
strncat(newStr, b, sizeof newStr - strlen(newStr) - 1); /* edited */
/* Presumably you do something with newStr here */
}
Примечания:
- Объявите тип возвращаемого значения для функции. Если вы не объявите это явно, ваш компилятор, вероятно, будет по умолчанию использовать
int
, но это плохой стиль и устаревшая языковая функция.
- Избегайте
strncat()
.
- Я использовал
'\0'
, а не NULL
, чтобы завершить строку нулем. NULL
- нулевой указатель константа; не используйте его для обозначения нулевого символа .
Здесь есть существенная неэффективность: второй strncat()
должен повторно сканировать с начала newStr
. Для небольшого количества коротких строк это не имеет большого значения, но для большого количества строк, объединяемых в большой целевой массив, это может вызвать серьезные замедления. Есть способы обойти это, но они либо нестандартны (strlcpy()
, strlcat()
), либо неудобны.
РЕДАКТИРОВАТЬ : Спасибо Мэтью за указание на ошибки в моем коде. Я думаю Я исправил их; Я уверен, что могу рассчитывать на то, что кто-то ударит меня по голове, если я заменю старые ошибки новыми.
Альтернатива:
snprintf(newStr, sizeof newStr, "%s%s", a, b);