Объединение двух константных символов * в C - PullRequest
0 голосов
/ 12 мая 2011

Я работаю с типом const char * в C. Из-за библиотек, которые я использую, я стараюсь не использовать или включать другие библиотеки (а именно, cstring).Функция, в которой я работаю, передается в буфер типа const char *.Я хочу добавить конечное сообщение в конец этого буфера.

Например:

functionA (const char *buffer){
    char *message = "hello world";
    //code appending message to the end of buffer
    //buffer now contains its original contents plus "hello world" at the end.
}

Я думаю, что лучший подход - создать временную переменную для получения данных избуфер, а затем добавьте сообщение.Как только это будет сделано, переназначьте указатель буфера на ссылку временной переменной (поскольку я пытаюсь сделать это с наименьшим количеством изменений в функции, чтобы уменьшить вероятность ошибки компиляции).

Ответы [ 9 ]

4 голосов
/ 12 мая 2011

Вы не можете добавить к const char *.Потому что это константа.

2 голосов
/ 12 мая 2011

Большинство упомянул две проблемы. Я добавлю третье:

  1. buffer указывает на постоянный символ, поэтому вы не можете писать в него.
  2. buffer передается по значению, поэтому переназначение не будет видно за пределами функции.
  3. Вы не представляете, насколько велик buffer, поэтому, если вы действительно сделали запись в него, вы можете вызвать переполнение буфера.

То, что вы можете (не проверено):

char* functionA(char* buffer, size_t maxlen)
{
    char *message = "hello world";
    if(strlen(buffer) + strlen(message) >= maxlen)
        return NULL;
    return strcat(buffer,message);
}

Длина двух строк должна быть меньше, чем maxlen, чтобы разрешить нулевое завершение.

strlen и strcat легко реализовать, если вы отказываетесь от их использования.

2 голосов
/ 12 мая 2011

Если вообще возможно избежать их объединения, не делайте этого. Например, если вы собираетесь отправить их как вывод, просто отправьте одно, а затем другое. Если вы хотите объединить их, вам нужно либо научиться использовать C ++, а не трактовать его как «C с дерьмовыми раздражающими ограничениями», либо сделать это способом C, который бы предусматривал выделение массива char, достаточно большого для размещения обеих строк. и копирование их на место (предпочтительно с snprintf).

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

1 голос
/ 12 мая 2011

Вы можете найти конечную позицию буфера [] и использовать ее в качестве места назначения для копии сообщения []. Подойдет любое сканирование учебника строки для терминала '\ 0', хотя вы должны быть уверены, что не вышли за пределы буфера [].

И это показывает большую проблему. Если вы понятия не имеете, насколько заполнен буфер и является ли ваше перемещение дополнительных 12 символов (считая автоматически поставляемый '\ 0' в конце) причиной переполнения буфера или нет, вам нужно каким-то образом узнать, что емкость буфера [] такова, что ваш код может работать в обороне.

Кроме того, хотя сделать const char * message = ... безопасно, буфер const char * кажется немного странным, если вы собираетесь его изменить. Хотя компилятор C может этого не заметить, это действительно нарушение договора, подразумеваемого использованием const char * buffer. Кроме того, вызывающей стороне разрешено использовать буфер [] в хранилище только для чтения, хотя я предполагаю, что вы являетесь единственным пользователем функции A.

Так что вы можете посмотреть, как изменить список параметров и определить интерфейс для этой функции, чтобы она могла защищаться от переполнений буфера, плохо инициализированных строк буфера [] и т. Д.

1 голос
/ 12 мая 2011

Я думаю, что ответы на Конкатенация строк в C, какой метод более эффективен? , в частности Конкатенация строк в C, какой метод более эффективен? , будет то, что вы ' ищу.

Но вам наверняка придется немного изменить свои аргументы. Вы не сможете изменить буфер в этом примере, так как он объявлен как const.

0 голосов
/ 31 июля 2013

Полагаю, если вы знаете, сколько памяти требуется для добавления сообщения, мы могли бы использовать memcpy.

что-то вроде ..

Main () { ...

u32 *new_ptr=NULL;
total_len=strlen(previous_msg)+strlen(appending_msg);
new_ptr=malloc(total_len);
memcpy(new_ptr,previous_msg,strlen(previous_msg));
memcpy(new_ptr+strlen(previous_msg), appending_msg, strlen(appending_msg));

... }

Теперь new_ptr будет содержать все сообщение.

0 голосов
/ 12 мая 2011

Как только это будет сделано, переназначить указатель буфера на ссылку временной переменной

Это только изменит то, на что указывает буфер внутри функции. Указатель, который вы передали в вызов функции, не будет изменен.

0 голосов
/ 12 мая 2011

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

char* combine (char *new_buffer, const char *buffer, const char *message)
{
    return strcat(strcpy(new_buffer, buffer), message);
}

Копирует строку в новый буфер, а затем объединяет в нее сообщение.

0 голосов
/ 12 мая 2011

Попробуйте использовать strcat (). strcat

...