2012-04-23 5 views
29

Как добавить один символ в строку в C?Добавить Char To String в C?

т.е.

char* str = "blablabla"; 
char c = 'H'; 
str_append(str,c); /* blablablaH */ 
+0

При условии, что ваше определение строки в строке 1 должно быть массивом символов с достаточной памятью, выделенной для него (как указано в ответах), попробуйте strncat (str, &c,1); для фактического добавления. –

ответ

24
char* str = "blablabla";  

Вы не должны изменять эту строку на всех. Он находится в области определения только для чтения. Модификация вызывает Неопределенное поведение.

Вам нужен массив символов, который не является строковым литералом.

Хорошо читать:
What is the difference between char a[] = "string"; and char *p = "string";

4

Я не думаю, что вы можете объявить строку типа, что в с. Вы можете сделать это только для const char *, и, конечно, вы не можете изменить const char *, поскольку он является const.

Вы можете использовать динамический массив символов, но вам придется позаботиться о перераспределении.

EDIT: на самом деле этот синтаксис правильно компилируется. Тем не менее вы можете не должны изменить то, что StR очков, если он инициализируется так, как вы это делаете (из строкового литерала)

+1

'char * ptr =" string "' отлично действует в C. –

+1

@Als - да, это правильно. Я думал, что это не так, но кажется, что все в порядке. Однако вы все равно не можете изменить массив. –

+1

Да, вы не можете изменить строковый литерал *, это не массив. –

22

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

Вот пример:

#include <stdlib.h> 

int main() 
{ 
    char *str = "blablabla"; 
    char c = 'H'; 

    size_t len = strlen(str); 
    char *str2 = malloc(len + 1 + 1); /* one for extra char, one for trailing zero */ 
    strcpy(str2, str); 
    str2[len] = c; 
    str2[len + 1] = '\0'; 

    printf("%s\n", str2); /* prints "blablablaH" */ 

    free(str2); 
} 

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

+0

Замечание об использовании sizeof неверен. 'sizeof str' - это 4 или 8 в зависимости от того, компилируете ли вы 32 или 64-битный код. – JeremyP

+0

Кроме того, всегда используйте спецификатор формата в printf. Представьте себе, что 'str' содержит в себе последовательность символов'% s'. – JeremyP

+0

@JeremyP Комментарий 'sizeof' действительно неточен. Я имел в виду, что вы можете называть 'sizeof (« blablablah »)', я просто удалю комментарий вообще, поскольку компилятор может быть достаточно умным, чтобы заметить, что он может согнуть вызов. Что касается спецификатора формата - вы, конечно, правы, очень смущающая ошибка. Я уточню свой ответ. –

1

C не имеет строк как таковых - у вас есть указатель на символ, указывающий на некоторую постоянную память, содержащую символы «blablabla \ 0». Чтобы добавить туда символ, вам понадобится: a) записываемая память и b) достаточно места для строки в ее новой форме. Строковый литерал «blablabla \ 0» не имеет ни одного.

Растворы:

1) Использование malloc() и др. для динамического выделения памяти. (Не забудьте затем free().)
2) Используйте массив символов.

При работе со строками рассмотрите варианты strn* функций str* - они помогут вам оставаться в пределах границ памяти.

+1

Но никогда не используйте 'strncpy'. Это не строковая функция (несмотря на ее название) и только вызывает проблемы. – melpomene

-3

вот, он работает 100%

char* appending(char *cArr, const char c) 

{ 

int len = strlen(cArr); 

cArr[len + 1] = cArr[len]; 

cArr[len] = c; 

return cArr; 


} 
+2

Это работает только в том случае, если строка, на которую указывает 'cArr', доступна для записи * и *, если у нее достаточно места для добавления другого символа. –

+7

-1, поскольку он работает только «100%» при очень малых значениях «100». –

2

Самый простой способ добавить две строки:

char * append(char * string1, char * string2) 
{ 
    char * result = NULL; 
    asprintf(&result, "%s%s", string1, string2); 
    return result; 
} 
+3

Если у вас есть нестандартная функция 'asprintf'; он не определяется ни языком C, ни POSIX. –

+0

Вы не возвращаете ссылку на локальную переменную? – Abhishek

+0

У меня никогда не было проблем с этим, возможно, asprintf выделяет память. –

2

Создать новую строку (строка + полукокса)

#include <stdio.h>  
#include <stdlib.h> 

#define ERR_MESSAGE__NO_MEM "Not enough memory!" 
#define allocator(element, type) _allocator(element, sizeof(type)) 

/** Allocator function (safe alloc) */ 
void *_allocator(size_t element, size_t typeSize) 
{ 
    void *ptr = NULL; 
    /* check alloc */ 
    if((ptr = calloc(element, typeSize)) == NULL) 
    {printf(ERR_MESSAGE__NO_MEM); exit(1);} 
    /* return pointer */ 
    return ptr; 
} 

/** Append function (safe mode) */ 
char *append(const char *input, const char c) 
{ 
    char *newString, *ptr; 

    /* alloc */ 
    newString = allocator((strlen(input) + 2), char); 
    /* Copy old string in new (with pointer) */ 
    ptr = newString; 
    for(; *input; input++) {*ptr = *input; ptr++;} 
    /* Copy char at end */ 
    *ptr = c; 
    /* return new string (for dealloc use free().) */ 
    return newString; 
} 

/** Program main */ 
int main (int argc, const char *argv[]) 
{ 
    char *input = "Ciao Mondo"; // i am italian :), this is "Hello World" 
    char c = '!'; 
    char *newString; 

    newString = append(input, c); 
    printf("%s\n",newString); 
    /* dealloc */ 
    free(newString); 
    newString = NULL; 

    exit(0); 
} 

       0 1 2 3 4 5 6 7 8 9 10 11 
newString is [C] [i] [a] [o] [\32] [M] [o] [n] [d] [o] [!] [\0] 

Не изменяйте размер массива ([len +1] и т. Д.), Не зная об этом точный размер, он может повредить другие данные. alloc массив с новым размером и вместо этого ставьте старые данные, помните, что для массива символов последнее значение должно быть \0; calloc() устанавливает все значения в \0, что отлично подходит для массивов char.

Надеюсь, это поможет.

2

Оригинальный плакат не хотел писать:

char* str = "blablabla"; 

но

char str[128] = "blablabla"; 

Теперь, добавив один символ будет казаться более эффективным, чем добавление целой строки с strcat. Идя strcat путь, вы можете:

char tmpstr[2]; 
    tmpstr[0] = c; 
    tmpstr[1] = 0; 
    strcat (str, tmpstr); 

, но вы также можете легко написать свою собственную функцию (как некоторые из них делали раньше меня):

void strcat_c (char *str, char c) 
    { 
    for (;*str;str++); // note the terminating semicolon here. 
    *str++ = c; 
    *str++ = 0; 
    } 
-1

В моем случае, это было самое лучшее решение Я нашел:

snprintf(str, sizeof str, "%s%c", str, c); 
+0

Это выглядит как неопределенное поведение для меня. Я не думаю, что вам разрешено передавать целевой аргумент 'str' в качестве одного из аргументов строки формата (' '% s ...", str, ... '). – melpomene

-4

в C++, вы можете просто добавить char к string по:

int main() 
{ 
    std::string s = "Hello there"; 
    char c = '?'; 
    s = s+c; 
    std::cout << s << std::endl; 
    return 0; 
} 
+1

Это C++, а не C. – melpomene