strncpy не работает должным образом

#include <iostream>
using namespace std
#include <string.h>
int main(){
char token[] = "some random string";
char c[23];
strcpy( c, token);
strncpy(c, token, 5);
c[strlen(c)] = '\0';
cout<<c;
return 0 ;
}

Мой вывод: some random string, Но я ожидаю, что это будет: some, Может кто-нибудь объяснить, почему он так себя ведет?

0

Решение

Я думаю, что ваш вывод должен быть «какой-то случайной строкой», потому что ваши две строки кода ничего не делают, смотрите комментарий.

int main(){
char token[] = "some random string";
char c[23];
strcpy( c, token);
strncpy(c, token, 5);  // Does nothing
c[strlen(c)] = '\0';   // Does nothing
cout<<c;
return 0 ;
}

Если вы хотите вывести «some», вы можете сделать это:

strncpy(c, token, 5);
c[5] = '\0';

strncpy () не добавляет автоматически завершающуюся ‘\ 0’ в строку dest. Если длина исходной строки больше, чем len (3-й аргумент strncpy), тогда символы len копируются в dest без завершающего символа ‘\ 0’. Таким образом, вы должны явно указывать завершающий символ ‘\ 0’ по коду.

3

Другие решения

Это работает просто отлично — имейте в виду, что strncpy не обязательно завершать строку нулем. Когда вы делаете это:

strncpy(c, token, 5);

Копирует первые 5 байтов token в c но не заканчивает нулем результат. Кроме того, эта строка бесполезна:

c[strlen(c)] = '\0';

strlen(c) ищет существующий нулевой терминатор, и как только вы его найдете, вы перезаписываете его другим нулевым терминатором, который не имеет смысла.

В новом коде strncpy должен редко, если вообще использоваться. Его предполагаемое использование (буферы фиксированной длины, которые не обязательно заканчиваются нулем) давно устарело. Предпочитаю вместо функции, как strlcpy (нота: strlcpy не является стандартным; это доступно только в BSD-подобных системах).

Или, если вы пишете код на C ++ вместо чистого C, просто используйте std::string и вообще избегайте таких хитрых вопросов.

6

Вам нужно завершить нулем после слова «some» вместо завершения нулем после всей строки. strncpy скопирует «some» в c, но это не обязательно завершит вашу строку null (см. man-страницу для strncpy)

c[4] = '\0'
1

Как уже упоминали другие, в отличие от snprintf в sprintf, strncpy не безопасная версия strcpy, Это просто гарантирует, что «ровно N символов будут скопированы в место назначения (используйте NUL, если исходная строка короче, чем N)». (справочная страница)

Но я думаю, что вы уже заметили, что по линии

c[strlen(c)] = '\0';

Это означало обеспечить нулевое прекращение c, Но это на самом деле бессмысленно, так как strlen использует NUL для определения длины c, Так что эта строка едва ли означает «найти NUL и написать NUL в это место».

Важность strncpy это скопировать определенную часть строки. Это не исправление strcpyи существовало до введения snprintf функции.

0
По вопросам рекламы [email protected]