Ответ 1
Ваши рассуждения верны и были бы легко подтверждены любым достойным руководством :
Функция
strcpy()
копирует строку, на которую указываетsrc
, включая завершающий нулевой байт ('\0'
), в буфер, на который указываетdest
.
При использовании функций строковой манипуляции, специфически strcpy
Я сделал эту небольшую программу.
char s1[8]="Hellopo";
char s2[4]="sup";
strcpy(s1,s2);
cout<<s1<<endl;
Когда я распечатал s1, на самом деле он просто распечатал "sup". Я ожидал, что он напечатает "suplopo".
Тогда я сделал это:
cout<<s1+4 << endl;
Он напечатал "opo";
И Результат этого: cout<<s1+3<<endl;
ничего не было
Итак, немного подумав об этом.
Я пришел к такому выводу. Поскольку С++ перестает выводить строку, когда она достигает нулевого терминатора. Поэтому нуль должен быть скопирован в функцию strcpy
. Результат в этой строке:
s - u - p -\0 - o - p - o -\0;
Скажите, пожалуйста, правильно это или нет. И если им не поправьте меня.
И если у вас есть дополнительная информация, пожалуйста, сделайте.
Ваши рассуждения верны и были бы легко подтверждены любым достойным руководством :
Функция
strcpy()
копирует строку, на которую указываетsrc
, включая завершающий нулевой байт ('\0'
), в буфер, на который указываетdest
.
Вы правы. Для эффекта, который вы изначально ожидали, вы использовали бы strncopy
. strncopy
копирует нулевой ограничитель, если вы указываете правильную длину копируемой строки.
Ваши аргументы относительно копирования завершающего символа верны. Стандарт С++ (который является окончательной спецификацией для языка) отсылает к C по этому вопросу (например, С++ 14 отступает на C99, а С++ 17 переходит на C11).
В стандарте C11 говорится об strcpy
:
7.24.2.3 Функция
strcpy
Описание:
#include <string.h>
char *strcpy(char * restrict s1, const char * restrict s2);
Описание:
Функция
strcpy
копирует строку, на которую указываетs2
(включая завершающий нулевой символ), в массив, на который указываетs1
. Если копирование происходит между перекрывающимися объектами, поведение undefined.Возврат:
Функция
strcpy
возвращает значениеs1
.
Если вам просто нужно заменить первые три символа вашей строки, вы можете использовать memcpy()
для копирования определенного количества байтов:
memcpy(s1, s2, strlen(s2));
Имейте в виду, что это просто скопирует эти байты и не более того. Если s1
уже не строка длиной не менее s2
, она вряд ли закончится хорошо: -)
И просто помните о своем комментарии "... в результате получается следующая строка: s u p \0 o p o \0".
Это не строка. Строка в C (и устаревшая строка в С++) определяется как последовательность символов вплоть до первого терминатора \0
.
У вас может быть серия символов до исходного (теперь второго) \0
, но строка на самом деле короче. Это может показаться немного педантичным, но важно понимать определения.
На странице man для strcpy
:
Функция
strcpy()
копирует строку, на которую указываетsrc
, включая завершающий нулевой байт ('\0'
), в буфер, на который указывает наdest
. Строки могут не перекрываться, а строка назначенияdest
должен быть достаточно большим, чтобы получить копию.
Это правильно.
http://pubs.opengroup.org/onlinepubs/009695399/functions/strcpy.html
Функция strcpy() должна скопировать строку, на которую указывает s2 (включая завершающий нулевой байт) в массив, на который указывает s1.
Да, это правильно. strcpy будет включать нулевой ограничитель. Важно, как если бы вы скопировали строку в новый блок памяти, вы хотите, чтобы он по умолчанию был отключен. Я считаю, что strncpy может быть тем, что вам нужно в этом случае.
Также я знаю, что это был только тестовый код, но я был бы осторожен в этот день и возраст использования смещений + X в строках... ascii обычно укусывает людей в тылу в мире utf8/unicode, в котором мы сейчас живем.
Да, вы правы в своих рассуждениях, и если бы вы явно указали тип 4-го символа 's1 [3]' как целое число следующим образом:
соиЬ << (целое) s1 [3];
Вы бы получили "0" в качестве вывода, который является значением ASCII символа NULL.