2012-04-23 14 views
29

¿Cómo agrego un solo carácter a una cadena en C?Añadir char a cadena en C?

es decir

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

Con la condición de que su definición de una cadena en la línea 1 tiene que ser una matriz de caracteres con suficiente memoria asignada a ella (como se detalla en las respuestas), trate strncat (str, &c,1); para la Anexión real. –

Respuesta

4

no creo que se puede declarar una cadena como la de c. Solo puede hacer eso para const char * y, por supuesto, no puede modificar un const char *, ya que es const.

Usted puede utilizar matriz de caracteres dinámico, pero que tendrá que hacerse cargo de la reasignación.

EDITAR: de hecho, esta sintaxis se compila correctamente. Todavía no se puede modificar lo que debe str puntos a si se ha inicializado en la forma que lo hace (de cadena literal)

+1

'char * ptr =" string "' es perfectamente válido en C. –

+1

@Als - sí, es correcto. Pensé que no, pero parece que está bien. Sin embargo, todavía no puede modificar la matriz. –

+1

Sí, no puede modificar el * literal de cadena * para empezar no es una matriz. –

22

para anexar un char a una cadena en C, primero hay que asegurarse de que el búfer de memoria que contiene la cadena es lo suficientemente grande para acomodar un carácter adicional. En su programa de ejemplo, tendría que asignar un nuevo bloque de memoria adicional porque la cadena literal dada no se puede modificar.

He aquí una muestra:

#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); 
} 

En primer lugar, utilizar malloc para asignar un nuevo trozo de memoria que es lo suficientemente grande como para dar cabida a todos los caracteres de la cadena de entrada, el carbón extra para anexar - y el cero final. Luego llame al strcpy para copiar la cadena de entrada en el nuevo buffer. Finalmente, cambie los últimos dos bytes en el nuevo buffer para virar el carácter que se agregará así como el cero final.

+0

El comentario sobre el uso de sizeof es incorrecto. 'sizeof str' es 4 u 8 dependiendo de si está compilando código de 32 o 64 bits. – JeremyP

+0

Además, siempre use un especificador de formato en printf. Imagine si 'str' contenía una secuencia de caracteres'% s'. – JeremyP

+0

@JeremyP El comentario 'sizeof' es realmente impreciso. Quise decir que puede llamar a 'sizeof (" blablablah ")', simplemente eliminaré el comentario ya que el compilador puede ser lo suficientemente inteligente como para darse cuenta de que puede contener la llamada. En cuanto al especificador de formato, tiene razón, por supuesto, un error muy embarazoso. Actualizaré mi respuesta. –

1

C no tiene cuerdas per se - lo que tienes es un puntero que apunta char a parte de la memoria de sólo lectura que contiene los caracteres "blablabla \ 0". Para agregar un carácter allí, necesita a) memoria grabable yb) suficiente espacio para la cadena en su nueva forma. La cadena literal "blablabla \ 0" no tiene ninguno.

Las soluciones son:

1) Usar malloc() et al. para asignar dinámicamente la memoria. (No se olvide de free() después.)
2) Use una matriz de caracteres.

Al trabajar con cadenas, considere utilizar las variantes strn* de las funciones str*, que le ayudarán a mantenerse dentro de los límites de la memoria.

+1

Pero nunca use 'strncpy'. No es una función de cadena (a pesar de su nombre) y solo causa problemas. – melpomene

-3

aquí es, que funciona al 100%

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

{ 

int len = strlen(cArr); 

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

cArr[len] = c; 

return cArr; 


} 
+2

Eso funciona solo si la cadena apuntada por 'cArr' es escribible * y * si tiene espacio suficiente para agregar otro carácter. –

+7

-1 ya que solo funciona "100%" para valores muy pequeños de "100". –

2

manera más fácil de añadir dos cadenas:

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

Si tiene la función 'asprintf' no estándar; no está definido ni por el lenguaje C ni por POSIX. –

+0

¿No devuelve una referencia a la variable local? – Abhishek

+0

Nunca tuve un problema con él, tal vez asprintf asigna la memoria. –

2

crear una nueva cadena (string + Char)

#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] 

No modifique el tamaño de la matriz ([len +1], etc.) sin saberlo s tamaño exacto, puede dañar otros datos. alloc una matriz con el nuevo tamaño y poner los datos antiguos dentro, recuerde que, para una matriz de caracteres, el último valor debe ser \0; calloc() establece todos los valores en \0, que es excelente para las matrices char.

Espero que esto ayude.

2

El cartel original no tenía intención de escribir:

char* str = "blablabla"; 

pero

char str[128] = "blablabla"; 

Ahora, la adición de un solo carácter parecería más eficiente que la adición de toda una cadena con strcat. va por el camino strcat, podrías:

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

pero también se puede escribir fácilmente su propia función (como varios lo han hecho antes que yo):

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

En mi caso, esta era la mejor solución he encontrado:

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

Eso me parece un comportamiento indefinido. No creo que se le permita pasar el argumento de destino 'str' como uno de los argumentos de la cadena de formato (' "% s ...", str, ... '). – melpomene

-4

en C++, sólo tiene que añadir un char a un string por:

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

Eso es C++, no C. – melpomene