Основной вопрос C о копировании массивов символов в указатели символов - PullRequest
2 голосов
/ 12 апреля 2011

У меня есть некоторые сомнения в базовом программировании на Си.

У меня есть массив символов, и я должен скопировать его в указатель на символ. Поэтому я сделал следующее:

char a[] = {0x3f, 0x4d};
char *p = a;     
printf("a = %s\n",a);
printf("p = %s\n",p);
unsigned char str[] = {0x3b, 0x4b};
unsigned char *pstr =str;
memcpy(pstr, str, sizeof str);
printf("str = %s\n",str);
printf("pstr = %s\n",pstr);

Мои операторы printf для pstr и str добавляются с данными "a". Если я удаляю memcpy, я получаю мусор. Может ли какой-то гуру просветить меня?

Ответы [ 6 ]

3 голосов
/ 12 апреля 2011

Во-первых, ожидается, что строки C (%s в printf) будут заканчиваться NUL.Вы скучаете по терминаторам.Попробуйте char a[] = {0x3f, 0x4d, 0} (то же самое относится и к str).

Во-вторых, pstr и str указывают на одну и ту же память, поэтому ваш memcpy не используется.Это второстепенный пункт по сравнению с первым.

2 голосов
/ 12 апреля 2011

Добавьте нулевой терминатор, потому что это то, что вы ожидаете от printf:

char a[] = {0x3f, 0x4d, '\0'};
1 голос
/ 12 апреля 2011

Стандартный способ представления C-строк состоит в том, что в памяти они представляют собой последовательность ненулевых байтов, представляющих символы, за которыми следует нулевой (или NULL) байт. Вы должны заявить:

char a[] = {0x3f, 0x4d, 0};

Когда вы назначаете строковый указатель (как в unsigned char *pstr = str;), оба указателя указывают на одну и ту же область памяти и, следовательно, на одни и те же символы. Нет необходимости копировать символы.

Когда вам нужно скопировать символы, вы должны использовать strlen(), оператор sizeof() возвращает количество байтов, которое его аргумент использует в памяти. sizeof(pointer) - это количество байтов, которые использует указатель, а не длина строки. Вы находите длину строки (то есть количество байтов, которое она занимает в памяти) с помощью функции strlen(). Также есть стандартные функции для копирования строк С. Вы должны полагаться на тех, кто поступает правильно:

strcpy(pstr, str);
0 голосов
/ 28 февраля 2018

Согласовано.Вам нужно будет добавить нулевой байт в конце вашего массива символов.

char a[] = {0x3f, 0x4d, '\0'};

Причина в том, что вы создаете строку без объявления, где она фактически заканчивается.Ваша функция memcpy () копирует * str в * pstr и автоматически добавляет нулевой байт для вас, поэтому она работает.

Без memcpy () там строка никогда не знает, когда заканчивать, поэтому она достигает следующегоадреса памяти и возвращает любые случайные значения, хранящиеся там.Когда вы создаете строку из символов, всегда не забывайте заканчивать ее нулевым байтом.

0 голосов
/ 12 апреля 2011

Вы объявляете массив "str", а затем указываете на него с помощью pstr.Обратите внимание, что у вас нет символа с нулевым символом в конце, поэтому после использования memcpy вы копируете блок в себя без нулевого терминатора, поскольку для строки требуется .Таким образом, printf не может найти конец строки и продолжает печатать, пока не найдет 0 (или '\ 0' в символьном выражении)

0 голосов
/ 12 апреля 2011

printf %s ожидает строку с нулем в конце, ваши строки - нет.Однако неинициализированная память, следующая за вашими массивами, может начинаться с 0-байтового кода, и в этом случае ваш код будет выглядеть правильным, но это не так.

...