¿Cómo concatenar dos cadenas en C ++?

100

Tengo una variable de clase privada char name[10]a la que me gustaría agregar la .txtextensión para poder abrir el archivo presente en el directorio.

¿Cómo hago con esto?

Sería preferible crear una nueva variable de cadena que contenga la cadena concatenada.

Slashr
fuente

Respuestas:

160

En primer lugar, no use char*o char[N]. ¡Úselo std::string, entonces todo lo demás se vuelve tan fácil!

Ejemplos,

std::string s = "Hello";
std::string greet = s + " World"; //concatenation easy!

Fácil, ¿no?

Ahora, si lo necesita char const *por alguna razón, como cuando desea pasar a alguna función, puede hacer esto:

some_c_api(s.c_str(), s.size()); 

asumiendo que esta función se declara como:

some_c_api(char const *input, size_t length);

Explore std::stringusted mismo comenzando desde aquí:

Espero que ayude.

Nawaz
fuente
3
¿Cuál es la complejidad temporal de esta concatenación de cadenas?
d34th4ck3r
@ d34th4ck3r: Es lineal.
Nawaz
30

Dado que es C ++, ¿por qué no usarlo en std::stringlugar de char*? La concatenación será trivial:

std::string str = "abc";
str += "another";
Nogard
fuente
1
Cabe señalar que el uso trivial viene con una etiqueta de precio no trivial con respecto al rendimiento en tiempo de ejecución. El peor de los casos es que operator+=realiza tanto una desasignación como una asignación. Las asignaciones de montón se encuentran entre las operaciones más caras que hacemos habitualmente.
Inspectable
15

Si estaba programando en C, entonces asumiendo que namerealmente es una matriz de longitud fija como dice, debe hacer algo como lo siguiente:

char filename[sizeof(name) + 4];
strcpy (filename, name) ;
strcat (filename, ".txt") ;
FILE* fp = fopen (filename,...

¿Ves ahora por qué todos recomiendan std::string?

TonyK
fuente
1
¿No ves que el tipo ha hecho una pregunta en C ++ y no en C?
IcyFlame
21
¿No ves que dije "Si estuvieras programando ..."?
TonyK
¿No cree que esta respuesta es irrelevante para esta pregunta?
IcyFlame
9
Creo que esto es relevante ya que "el tipo" está usando char en lugar de std :: string. Además, muestra una forma explícita de concatenación que no se mostró en la respuesta más votada. Al menos aprendí algo con él.
gvegayon
1
Esto también muestra un método para realizar una concatenación de cadenas sin asignación de memoria dinámica. A menos que me equivoque, std :: string operator + = requiere una posible reasignación.
Ashley Duncan
7

Hay un strcat () de la biblioteca C portada que hará la concatenación de "cadenas de estilo C" por usted.

Por cierto, aunque C ++ tiene un montón de funciones para lidiar con cadenas de estilo C, podría ser beneficioso que intente crear su propia función que haga eso, algo como:

char * con(const char * first, const char * second) {
    int l1 = 0, l2 = 0;
    const char * f = first, * l = second;

    // step 1 - find lengths (you can also use strlen)
    while (*f++) ++l1;
    while (*l++) ++l2;

    char *result = new char[l1 + l2];

    // then concatenate
    for (int i = 0; i < l1; i++) result[i] = first[i];
    for (int i = l1; i < l1 + l2; i++) result[i] = second[i - l1];

    // finally, "cap" result with terminating null char
    result[l1+l2] = '\0';
    return result;
}

...y entonces...

char s1[] = "file_name";
char *c = con(s1, ".txt");

... cuyo resultado es file_name.txt.

También puede tener la tentación de escribir el suyo propio, operator +sin embargo, el operador IIRC se sobrecarga con solo punteros, ya que no se permiten argumentos.

Además, no olvide que el resultado en este caso se asigna dinámicamente, por lo que es posible que desee llamar a eliminar para evitar pérdidas de memoria, o puede modificar la función para usar una matriz de caracteres asignada a la pila, siempre que, por supuesto, tenga la longitud suficiente.

dtech
fuente
Vea mi comentario a la respuesta de IcyFlame.
TonyK
3
También hay una strncat()función que suele ser una mejor alternativa
nogard
@nogard: strncataquí es irrelevante, porque ya conocemos la longitud del segundo parámetro ".txt". Así sería strncat(name, ".txt", 4), lo que no nos gana nada.
TonyK
0

Es mejor usar la clase de cadena C ++ en lugar de la cadena C de estilo antiguo, la vida sería mucho más fácil.

si tiene una cadena de estilo antiguo existente, puede convertirla en una clase de cadena

    char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    cout<<greeting + "and there \n"; //will not compile because concat does \n not work on old C style string
    string trueString = string (greeting);
    cout << trueString + "and there \n"; // compiles fine
    cout << trueString + 'c'; // this will be fine too. if one of the operand if C++ string, this will work too
i.AsifNoor
fuente
0

C ++ 14

std::string great = "Hello"s + " World"; // concatenation easy!

Responde a la pregunta:

auto fname = ""s + name + ".txt";
SM
fuente
-2
//String appending
#include <iostream>
using namespace std;

void stringconcat(char *str1, char *str2){
    while (*str1 != '\0'){
        str1++;
    }

    while(*str2 != '\0'){
        *str1 = *str2;
        str1++;
        str2++;
    }
}

int main() {
    char str1[100];
    cin.getline(str1, 100);  
    char str2[100];
    cin.getline(str2, 100);

    stringconcat(str1, str2);

    cout<<str1;
    getchar();
    return 0;
}
Kartik
fuente