C добавление char для char *

Поэтому я пытаюсь добавить char char* .

Например, у меня есть char *word = " "; У меня также есть char ch = 'x';

Я append(word, ch); Используя этот метод ..

 void append(char* s, char c) { int len = strlen(s); s[len] = c; s[len+1] = '\0'; } 

Это дает мне ошибку сегментации, и я понимаю, почему я предполагаю. Потому что s[len] вне пределов. Как сделать так, чтобы он работал? Мне также нужно очистить char* , если бы я использовал что-то вроде char word [500]; Как я могу это понять, если у него есть некоторые персонажи, прикрепленные к нему? Будет ли она равна 500 ? Заранее спасибо.

Типичная практика C была бы такой:

 //returns 1 if failed, 0 if succeeded int append(char*s, size_t size, char c) { if(strlen(s) + 1 >= size) { return 1; } int len = strlen(s); s[len] = c; s[len+1] = '\0'; return 0; } 

При передаче функции массив для изменения функции не имеет представления во время компиляции, сколько места у него есть. Обычная практика в C также должна передавать длину массива, и функция будет доверять этой привязке и терпеть неудачу, если она не сможет выполнить свою работу в пространстве, которое она имеет. Другой вариант – перераспределить и вернуть новый массив, вам нужно будет вернуть char* или принять char** в качестве входных данных, но вы должны тщательно подумать о том, как управлять памятью кучи в этой ситуации. Но без перераспределения, да, ваша функция должна каким-то образом потерпеть неудачу, если ее попросят добавить, когда нет свободного места, вам нужно, как сбой.

Трудно добавить к строке на месте в C. Попробуйте что-то вроде этого:

 char *append(const char *s, char c) { int len = strlen(s); char buf[len+2]; strcpy(buf, s); buf[len] = c; buf[len + 1] = 0; return strdup(buf); } 

Обязательно освободите возвращаемую строку, когда закончите с ней.

FYI: Вероятно, это связано с тем, что строка, которую вы передаете, хранится в памяти только для чтения. Но вы правы, вы также списываете с конца (запись [len+1] , а не [len] ).

Если вы проходите мимо

 append("foo", 'X'); 

он сработает, потому что foo обычно помещается в хранилище только для чтения. Даже если это не так, это может переписать что-то плохое! В этом случае компилятор, если он добр, должен предупредить вас о преобразовании из const char * в char *, который будет ключом.

Да, допущение, которое вы сделали, – почти – правильно – авария может быть связана с тем, что вы пытаетесь написать прошлые границы строки (на самом деле только s[strlen(s) + 1] выходит за пределы, потому что s[strlen(s)] по-прежнему является допустимым местом – там хранится завершающий байт NUL). Но вы также не можете модифицировать строковый литерал, потому что обычно он находится в некоторой части памяти процесса. Оба эти действия приводят к вызову неопределенного поведения, которое может привести к сбою. Вы можете решить эту проблему, скопировав строку в динамически распределенное хранилище, а затем изменив копию. Кроме того, вы должны использовать const char * в аргументе вашей функции, потому что char * предполагает, что строки только для чтения не могут быть переданы.

 char *append(const char *orig, char c) { size_t sz = strlen(orig); char *str = malloc(sz + 2); strcpy(str, orig); str[sz] = c; str[sz + 1] = '\0'; return str; } 

Кроме того, не забудьте free() возвращаемую строку, когда она больше не нужна.

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

В частности, если вы делаете char x [500];

нет гарантии, что strlen (x) вернет вам 500. Он вернет вам, сколько символов ему нужно пересчитать с начала x до того, как оно достигнет нуля. Он может вернуть вам 0, 1 … 500, 501 …, в зависимости от того, что находится в x.

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