2010-01-03 20 views
85

necesito para concatenar dos caracteres const como éstas:const char * concatenación

const char *one = "Hello "; 
const char *two = "World"; 

¿Cómo podría yo ir haciendo eso?

Me pasé estos char* s de una biblioteca de terceros con una interfaz C, así que no puedo simplemente usar std::string en su lugar.

+5

I Estoy confundido: el interlocutor original escribió la etiqueta "C++" y luego alguien más lo eliminó. ¿Cuál es el estado de las cosas para esta pregunta? ¿Está permitido el código C++? –

+0

@Johannes: Esa es una mejor pregunta xD. –

+0

También tenga en cuenta que la pregunta original NO se refirió a C: he eliminado esa etiqueta. –

Respuesta

75

En su ejemplo uno y dos son punteros de carbonilla, que apunta a char constantes. No puede cambiar las constantes de caracteres apuntadas por estos punteros. Así que cualquier cosa como:

strcat(one,two); // append string two to string one. 

no funcionará. En su lugar, debe tener una variable separada (matriz de caracteres) para contener el resultado. Algo como esto:

char result[100]; // array to hold the result. 

strcpy(result,one); // copy string one into the result. 
strcat(result,two); // append string two to the result. 
+0

¡Ja! Había usado strcpy y strcat y no funcionó, pero esa fue la única forma en que no lo intenté, ¡gracias! –

+2

¿por qué lo etiquetó C++? ... –

+0

@Anthoni: De nada :) – codaddict

27

Si está utilizando C++, ¿por qué no se utiliza std::string en lugar de cadenas de tipo C?

std::string one="Hello"; 
std::string two="World"; 

std::string three= one+two; 

Si necesita pasar esta cadena en un C-función, simplemente pasan three.c_str()

+5

Porque estoy usando una biblioteca que fue codificada en C por lo que las funciones devuelven const char * –

+4

Luego la etiqueta es engañosa. –

+3

Bueno, estoy codificando en Cpp. –

17

Usando std::string:

#include <string> 

std::string result = std::string(one) + std::string(two); 
+6

La segunda llamada explícita al constructor no es necesaria – sellibitze

5

En primer lugar, usted tiene que crear un espacio de memoria dinámica. Entonces puedes poner las dos cuerdas en él. O puede usar la clase C++ "string". La forma de la vieja escuela C:

char* catString = malloc(strlen(one)+strlen(two)+1); 
    strcpy(catString, one); 
    strcat(catString, two); 
    // use the string then delete it when you're done. 
    free(catString); 

Nueva C++ manera

std::string three(one); 
    three += two; 
+0

¿por qué necesita memoria dinámica? –

+4

-1 para mí, primero con el C-way que necesitas para usar malloc y gratis. Entonces, incluso si hace algo nuevo, entonces debería eliminar [] y no eliminar. – Naveen

+0

La biblioteca que estoy utilizando está codificada en C, no en C++, por lo que todas las funciones devuelven const char * not string. –

57

la forma en C:

char buf[100]; 
strcpy(buf, one); 
strcat(buf, two); 

El C++ manera:

std::string buf(one); 
buf.append(two); 

el tiempo de compilación manera:

#define one "hello " 
#define two "world" 
#define concat(first, second) first second 

const char* buf = concat(one, two); 
6

Un ejemplo más:

// calculate the required buffer size (also accounting for the null terminator): 
int bufferSize = strlen(one) + strlen(two) + 1; 

// allocate enough memory for the concatenated string: 
char* concatString = new char[ bufferSize ]; 

// copy strings one and two over to the new buffer: 
strcpy(concatString, one); 
strcat(concatString, two); 

... 

// delete buffer: 
delete[] concatString; 

Pero a menos que específicamente no desea o no puede utilizar la biblioteca de C++ estándar, utilizando std::string es probablemente más seguro.

+1

Si el OP no puede usar C++, no puede usar 'new'. Y si puede usarlo, debería usar 'std :: string', como dices. –

3

Puede usar strstream. Está formalmente obsoleto, pero sigue siendo una gran herramienta si necesitas trabajar con cadenas C, creo.

char result[100]; // max size 100 
std::ostrstream s(result, sizeof result - 1); 

s << one << two << std::ends; 
result[99] = '\0'; 

Esto escribirá one y luego two en la corriente, y anexar una terminación \0 usando std::ends. En caso de que ambas cadenas puedan terminar escribiendo exactamente 99 caracteres, por lo que no quedará espacio para escribir \0 - escribimos uno manualmente en la última posición.

+0

La depreciación no debería importar demasiado. Incluso si se elimina de una versión futura del estándar, no es tanto trabajo volver a implementar en su propio espacio de nombres. –

+0

@Steve, de hecho :) Y escribir su propia salida de direccionamiento 'streambuf' a un búfer de char usado con' ostream' tampoco es demasiado difícil. –

5

Parece que está utilizando C++ con una biblioteca C y, por lo tanto, necesita trabajar con const char *.

Sugiero envolver los const char * en std::string:

const char *a = "hello "; 
const char *b = "world"; 
std::string c = a; 
std::string d = b; 
cout << c + d; 
+2

¿Qué tal un ejemplo de c_str()? – sellibitze

3
const char* one = "one"; 
const char* two = "two"; 
char result[40]; 
sprintf(result, "%s%s", one, two); 
16

Actualización: cambió string total = string(one) + string(two); a string total(string(one) + two); por razones de rendimiento (evita la construcción de la cadena de dos y el total de cadena temporal)

const char *one = "Hello "; 
const char *two = "World"; 

string total(string(one) + two); // OR: string total = string(one) + string(two); 
// string total(move(move(string(one)) + two)); // even faster? 

// to use the concatenation in const char* use 
total.c_str() 
+0

no es muy efectivo en velocidad, no es una buena solución – Iburidu

+0

@iburidu ¿lo has medido? ¿Y las situaciones en que la seguridad supera al rendimiento? (Son situaciones comunes) – Sqeaky

+3

@Sqeaky No hay absolutamente ninguna situación en que esto sea más seguro que cualquier otra solución, pero SIEMPRE es más lento que una solución de tiempo de compilación, al invocar el comportamiento del tiempo de ejecución y al invocar la asignación de memoria. – Alice

0

conectar dos puntero char constante sin necesidad de utilizar comandos strcpy en la asignación dinámica de memoria:

const char* one = "Hello "; 
const char* two = "World!"; 

char* three = new char[strlen(one) + strlen(two) + 1] {'\0'}; 

strcat_s(three, strlen(one) + 1, one); 
strcat_s(three, strlen(one) + strlen(two) + 1, two); 

cout << three << endl; 

delete[] three; 
three = nullptr; 
1

Si no conoce el tamaño de las cuerdas, se puede hacer algo como esto:

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

int main(){ 
    const char* q1 = "First String"; 
    const char* q2 = " Second String"; 

    char * qq = (char*) malloc((strlen(q1)+ strlen(q2))*sizeof(char)); 
    strcpy(qq,q1); 
    strcat(qq,q2); 

    printf("%s\n",qq); 

    return 0; 
}