Зачем нам нужно использовать strcpy()
для копирования строки в массив символов?
Я потратил впустую свои 2 часа в этом. Он не показал мне никаких ошибок, но результат был не таким, как я ожидал, и я боролся 2 часа, чтобы узнать об ошибке.
Он просто показывал мусор.
когда я использую strcpy()
он работает нормально.
Другая интерпретация ответов состоит в том, что массив символов является базовым типом, а не классом, operator =
которого operator =
переопределен.
Как упоминалось в @StianV.Svendenborg, что присвоение массива символов другому означает назначение его адреса другой переменной указателя char.
распределение массива символов, например;
char test[4]={1,2,3,4};
приведет к распределению 4 байтов (каждый для значения char).
В выражениях, таких как арифметика, результат test
будет вести себя как указатель. Например, test+1
укажет адрес второго элемента и *(test+1) == 2
будет true, а print("%p",test)
будет напечатайте адрес первого элемента в вашем массиве.
Если вы используете класс std::string
и operator=
, функция будет проходить через все эти выделенные поля и скопировать их без вашего рассмотрения.
Длительный ответ:
После того, как вы объявили какой-либо массив в C++, будь то массив int, char or MyClass
любое использование имени этого массива по существу совпадает с указателем на первый элемент массива. Это становится ужасно очевидным, как только массив распределяется динамически, но также имеет место для статически распределенных массивов.
Это означает, что следующий код:
char arr[] = "Lorum ipsum";
Означает:
Выделите достаточно места для 12 символов в стеке, и пусть arr будет выглядеть как указатель на первый символ, этот указатель будет const (т.е. то, что указывает на то, что нельзя изменить.)
Таким образом, если вы попытаетесь написать:
const char * arr2 = "hello";
arr = arr2; // Error
То, что вы действительно задаете, это: Изменить arr
, который ведет себя как указатель, который нельзя изменить, чтобы теперь указать на первый символ в этой константной строке. Это запрещено.
При этом, если вместо этого вы используете указатель на константные строки, вы можете использовать описанный синтаксис:
const char * cstr1 = "Hello";
const char * cstr2 = "Bye";
cstr1 = cstr2; // All is good, you are only changing which
// c-string in the global data you are pointing to.
Так называемые C-строки, созданные на языке C, не имеют языковых функций высокого уровня для обработки строк. Здесь есть две разные концепции, которые вам нужно понять:
"abc"
, ""
, "my string literal"
Первыми из них являются немодифицированные (modyfing them - UB) массивы типа char[n]
, где n
- количество действительных символов плюс нулевой символ '\0'
, который представляет конец строки и должен всегда присутствовать. Вы можете получить доступ к своим отдельным элементам, используя оператор subscipting массива, например, например, "abc"[1]
в символ 'b'
.
Во-вторых, это запрограммированные программированием массивы, которые могут содержать C-строку. Например:
#define STR_LEN 60
char str[STR_LEN+1] = "abc";
Не путайте инициализатор массива с строковым литералом "abc"
, то же самое не то же самое. Фактически такой initiliazer (для этого размера массива) эквивалентен:
char str[STR_LEN+1] = {'a', 'b', 'c', '\0'};
Для обработки строковых литералов нужен указатель char
, а не char
array:
char *p_str = "abc" /* "abc" is string literal */
После объявления массива char
вы не можете напрямую передать строковый литерал, например:
str = "def"; /* wrong, str is array, not pointer (not l-value) */
Единственный способ присвоить новую строку массиву (строковая переменная) - это изменить его элементы, например:
str[0] = 'd';
str[1] = 'e';
str[2] = 'f';
str[3] = '\0'; /* very important */
Вместо назначения отдельных символов вы можете написать функцию, чтобы сделать это для вас, например:
char *my_strcpy(char dst[], const char *src)
{
while ((*dst++ = *src++)) /* copying idiom */
;
return dst;
}
Примеры вызовов:
my_strcpy(str, "def");
my_strcpy(str, p_str);
Вместо того, чтобы писать свою собственную функцию, вы можете просто использовать strcpy
(или немного безопаснее strncpy
), чтобы сделать это за вас. Конец истории.
Короткий ответ:
Для эффективности. Для людей, которые не хотят, чтобы массив был скопирован.
Когда вы используете необработанные указатели, вам необходимо учитывать все эти детали, такие как управление памятью, поведение при копировании и т.д., Для достижения ваших собственных требований к производительности. В другом случае вы можете использовать std::string
, который был разработан для удовлетворения большинства нормальных случаев.
Короткий ответ:
Это связано с тем, что массивы выделяют память статически, и вы не можете их повторно инициализировать.
Размер массива фиксирован.
Вместо этого вы можете использовать std::string
.
Хотя, вы можете использовать указатель char*
как это.
std::string
и оставить все позади