почему массив символов нельзя скопировать следующим образом: charArray = «некоторая строка»;

0

Зачем нам нужно использовать strcpy() для копирования строки в массив символов?

Я потратил впустую свои 2 часа в этом. Он не показал мне никаких ошибок, но результат был не таким, как я ожидал, и я боролся 2 часа, чтобы узнать об ошибке.

Он просто показывал мусор.

когда я использую strcpy() он работает нормально.

  • 10
    почему бы не использовать std::string и оставить все позади
  • 0
    Да, я использовал std :: string, но в моем проекте есть какой-то устаревший код c, и мне снова нужно преобразовать эту строку в char.
Показать ещё 6 комментариев
Теги:
string

5 ответов

2

Другая интерпретация ответов состоит в том, что массив символов является базовым типом, а не классом, 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=, функция будет проходить через все эти выделенные поля и скопировать их без вашего рассмотрения.

  • 0
    Массив не является указателем.
  • 0
    Я пытался объяснить поведение.
Показать ещё 4 комментария
1

Длительный ответ:

После того, как вы объявили какой-либо массив в 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.
0

Так называемые 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), чтобы сделать это за вас. Конец истории.

0

Короткий ответ:
Для эффективности. Для людей, которые не хотят, чтобы массив был скопирован.

Когда вы используете необработанные указатели, вам необходимо учитывать все эти детали, такие как управление памятью, поведение при копировании и т.д., Для достижения ваших собственных требований к производительности. В другом случае вы можете использовать std::string, который был разработан для удовлетворения большинства нормальных случаев.

0

Короткий ответ:
Это связано с тем, что массивы выделяют память статически, и вы не можете их повторно инициализировать.
Размер массива фиксирован.
Вместо этого вы можете использовать std::string.

Хотя, вы можете использовать указатель char* как это.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню