Сделайте копию символа * - PullRequest
       7

Сделайте копию символа *

8 голосов
/ 27 января 2009

У меня есть функция, которая принимает char * в качестве одного из своих параметров. Мне нужно манипулировать им, но оставить оригинальный символ * нетронутым. По сути, я хочу создать рабочую копию этого символа *. Кажется, это должно быть легко, но я действительно изо всех сил.

Моя первая (наивная) попытка была создать еще один символ * и установить его равным оригиналу:

char* linkCopy = link;

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

Должен ли я использовать strncpy для достижения этой цели?

Я пробовал следующее, но это вызывает сбой:

char linkCopy[sizeof(link)] = strncpy(linkCopy, link, sizeof(link));

Я что-то упускаю из виду ...?

РЕДАКТИРОВАТЬ: Мои извинения, я пытался упростить примеры, но я оставил некоторые из более длинных имен переменных во втором примере. Исправлено.

Ответы [ 7 ]

25 голосов
/ 27 января 2009

sizeof даст вам размер указателя. Это часто 4 или 8 в зависимости от вашего процессора / компилятора, но не от размера указанной строки. Вы можете использовать strlen и strcpy:

// +1 because of '\0' at the end
char * copy = malloc(strlen(original) + 1); 
strcpy(copy, original);
...
free(copy); // at the end, free it again.

Я видел несколько ответов, в которых предлагается использовать strdup, но это функция posix, а не часть C.

16 голосов
/ 27 января 2009

Возможно, вы захотите взглянуть на функцию strdup (man strdup):

char *linkCopy = strdup(link);

/* Do some work here */

free(linkCopy);

Редактировать : И поскольку вам нужно, чтобы он был стандартным C, сделайте так, как указали другие:

char *linkCopy = malloc(strlen(link) + 1);
/* Note that strncpy is unnecessary here since you know both the size
 * of the source and destination buffers
 */
strcpy(linkCopy, link);

/* Do some work */

free(linkCopy);

Поскольку strdup () не соответствует стандарту ANSI / ISO C, если он недоступен во время выполнения вашего компилятора, продолжайте и используйте это:

/*
**  Portable, public domain strdup() originally by Bob Stout
*/

#include <stdlib.h>
#include <string.h>

char* strdup(const char* str)
{
      char* newstr = (char*) malloc( strlen( str) + 1);

      if (newstr) {
          strcpy( newstr, str);
      }

      return newstr;
}
1 голос
/ 28 января 2009

Некоторые ответы, в том числе принятые, немного отклонены. Вы не strcpy строка, которую вы только что strlen 'd. strcpy не должно использоваться вообще в современных программах.

Что нужно сделать, это memcpy .

РЕДАКТИРОВАТЬ: memcpy очень , вероятно, будет быстрее в любой архитектуре, strcpy может работать лучше только для очень коротких строк и его следует избегать по соображениям безопасности, даже если они не имеют отношения в этом случае.

1 голос
/ 27 января 2009

Используйте strdup или strndup, если вы знаете размер (более безопасный).

Как:

char* new_char = strdup(original);
... manipulate it ...
free(new_char)

пс .: не стандарт C

0 голосов
/ 27 января 2009

Вы не говорите, можете ли вы использовать C ++ вместо C, но если вы можете использовать C ++ и STL, это еще проще:

std::string newString( original );

Используйте newString, как если бы вы использовали копию в стиле C выше, ее семантика идентична. Вам не нужно free() это, это стековый объект, который будет удален автоматически.

0 голосов
/ 27 января 2009

Как сказал sean.bright, strdup () - самый простой способ справиться с копией. Но strdup (), хотя и широко доступен, не является std C. Этот метод также сохраняет скопированную строку в куче.

char *linkCopy = strdup(link);

/* Do some work here */

free(linkCopy);

Если вы намерены использовать выделенную стеком строку и strncpy (), вам нужно внести некоторые изменения. Вы написали:

char linkCopy[sizeof(link)]

Это создает массив символов (он же строка) в стеке размером с указатель (вероятно, 4 байта). Ваш третий параметр strncpy () имеет ту же проблему. Вы, вероятно, хотите написать:

char linkCopy[strlen(link)+1];
strncpy(linkCopy,link,strlen(link)+1);
0 голосов
/ 27 января 2009

Вы на правильном пути, вам нужно использовать strcpy / strncpy для создания копий строк. Просто назначая их, вы создаете «псевдоним», другое имя, которое указывает на одно и то же.

Ваша главная проблема во второй попытке - вы не можете назначить массив таким образом. Вторая проблема в том, что вы, кажется, нашли в вызове функции несколько новых имен, которые я не могу сказать, откуда они взялись.

То, что вы хотите:

char linkCopy[sizeof(link)];
strncpy(linkCopy, chLastLink, sizeof(link));

но будьте осторожны, sizeof не всегда работает так, как вы хотите, для строк. Используйте strlen или strdup.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...