C – зачем нужен strcpy ()
Может кто-нибудь объяснить мне, почему strcpy () необходимо для назначения строк массивам символов, например, в следующем fragmentе кода.
int main(void) { char s[4]; s = "abc"; //Fails strcpy(s, "abc"); //Succeeds return 0; }
В чем причина неудачи s = "abc"
? И почему strcpy () единственный способ назначить строки массивам char после их объявления? Мне кажется странным, что вам нужно использовать функцию для выполнения основного задания.
- Может ли действующая строка Unicode содержать FFFF? Является ли Java / CharacterIterator нарушенным?
- Проблема сортировки строк в C #
- Почему byteArray имеет длину 22 вместо 20?
- Легальность реализации COW std :: string в C ++ 11
- Создавайте дружественные URL-адреса SEO (пули)
- Неявное преобразование из char ** в const char **
- Почему char предпочитает использовать String для паролей?
- Максимальная длина длины строки содержимого (8192) была превышена при чтении XML-данных
- Извлечение пар слов с помощью String.split ()
- Есть ли простой способ преобразования C ++ enum в строку?
- Java: диапазон индексов подстроки
- Как преобразовать String в InputStream в Java?
- Как сделать токенизацию строки в C ++?
Массивы в C не назначаются и не копируются. Вот как массивы находятся в C. Исторически, в контексте ценности (по RHS присвоения) массивы распадаются на указатели, что формально предотвращает назначение и копирование-инициализацию. Это относится ко всем массивам, а не только к массивам char
.
Язык C наследует поведение этих массивов от его предшественников – языков B и BCPL. В этих языках массивы были представлены физическими указателями. (И, очевидно, повторное назначение указателей – это не то, что вы хотели бы сделать, когда вы назначаете один массив другому.) В языках C массивы не являются указателями, но они «имитируют» историческое поведение массивов B и BCPL путем разложения для указателей в большинстве случаев. Это историческое наследие – это то, что сохраняет C массивы, не скопируемые до сих пор.
Одним из исключений из вышеизложенного является инициализация строковым литералом. Т.е. вы можете делать
char c[] = "abc";
но это все.
Это означает, что всякий раз, когда вы хотите скопировать массив, вы должны использовать функцию копирования памяти на уровне библиотеки, например memcpy
. strcpy
– это просто аромат, специально предназначенный для работы со строками.
Это просто, какие массивы находятся в C. Вы не можете назначать им. Вы можете использовать указатели, если хотите:
char *p; p = "abc";
Кстати, есть FAQ по C.
Массивы являются «гражданами второго сорта» в C; один из этих предрассудков состоит в том, что вы не можете назначить их .
Короткий ответ: исторические причины. C никогда не имел встроенного строкового типа. Только после того, как C ++ появился, возникла эта std :: string, и даже это не пришло с первой реализацией
Длинный ответ: тип «abc» не является char[]
, а скорее char *
. strcpy
– это один из механизмов, с помощью которого вы можете скопировать данные, на которые указывает указатель (в данном случае это ABC).
strcpy
– это не единственный способ инициализации массива, однако он достаточно умен, чтобы обнаруживать и уважать завершение 0 в конце строки. Вы также можете использовать memcpy
для копирования строки в s
но для этого требуется передать длину данных, подлежащих копированию, и обеспечить завершение 0 (NULL) в s
На языке C отсутствует удобный синтаксис для получения указателя на строковый литерал вместе с указанием его длины. Некоторые языки, включая много диалектов Паскаля, префикс каждой строки с байтом, сообщающим о своей длине; это хорошо работает для многих целей, но ограничивает строковые литералы до 255 символов. Подход C позволяет использовать строковые литералы любой длины, но добавляет только один байт служебных данных независимо от длины.
Строки с нулевым завершением уступают другим формам почти для всех целей, отличных от строковых литералов, но литералы настолько далеко отстоят от самой распространенной формы строки, с которой приходится сталкиваться многим программам, и, следовательно, есть значительное преимущество в отношении наличия библиотечных функций иметь дело с ними эффективно; тогда становится проще использовать строки с нулевым завершением в случаях, когда они менее идеальны, чем иметь отдельный набор библиотечных подпрограмм для других типов.