Подтвердить что ты не робот

С++: strcpy Функция копирует null?

При использовании функций строковой манипуляции, специфически 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;

Скажите, пожалуйста, правильно это или нет. И если им не поправьте меня.

И если у вас есть дополнительная информация, пожалуйста, сделайте.

4b9b3361

Ответ 1

Ваши рассуждения верны и были бы легко подтверждены любым достойным руководством :

Функция strcpy() копирует строку, на которую указывает src, включая завершающий нулевой байт ('\0'), в буфер, на который указывает dest.

Ответ 2

Вы правы. Для эффекта, который вы изначально ожидали, вы использовали бы strncopy. strncopy копирует нулевой ограничитель, если вы указываете правильную длину копируемой строки.

Ответ 3

Ваши аргументы относительно копирования завершающего символа верны. Стандарт С++ (который является окончательной спецификацией для языка) отсылает к 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, но строка на самом деле короче. Это может показаться немного педантичным, но важно понимать определения.

Ответ 4

На странице man для strcpy:

Функция strcpy() копирует строку, на которую указывает src, включая завершающий нулевой байт ('\0'), в буфер, на который указывает на dest. Строки могут не перекрываться, а строка назначения dest должен быть достаточно большим, чтобы получить копию.

Ответ 5

Это правильно.

http://pubs.opengroup.org/onlinepubs/009695399/functions/strcpy.html

Функция strcpy() должна скопировать строку, на которую указывает s2 (включая завершающий нулевой байт) в массив, на который указывает s1.

Ответ 6

Да, это правильно. strcpy будет включать нулевой ограничитель. Важно, как если бы вы скопировали строку в новый блок памяти, вы хотите, чтобы он по умолчанию был отключен. Я считаю, что strncpy может быть тем, что вам нужно в этом случае.

Также я знаю, что это был только тестовый код, но я был бы осторожен в этот день и возраст использования смещений + X в строках... ascii обычно укусывает людей в тылу в мире utf8/unicode, в котором мы сейчас живем.

Ответ 7

Да, вы правы в своих рассуждениях, и если бы вы явно указали тип 4-го символа 's1 [3]' как целое число следующим образом:

соиЬ << (целое) s1 [3];

Вы бы получили "0" в качестве вывода, который является значением ASCII символа NULL.