Comment concaténer deux chaînes en C ++?

100

J'ai une variable de classe privée char name[10]à laquelle je voudrais ajouter l' .txtextension afin que je puisse ouvrir le fichier présent dans le répertoire.

Comment dois-je procéder?

Il serait préférable de créer une nouvelle variable de chaîne contenant la chaîne concaténée.

Slashr
la source

Réponses:

160

Tout d'abord, n'utilisez pas char*ou char[N]. Utilisez std::string, alors tout le reste devient si simple!

Exemples,

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

Facile, non?

Maintenant, si vous avez besoin char const *pour une raison quelconque, comme lorsque vous voulez passer à une fonction, vous pouvez le faire:

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

en supposant que cette fonction est déclarée comme:

some_c_api(char const *input, size_t length);

Explorez- std::stringvous à partir d'ici:

J'espère que cela pourra aider.

Nawaz
la source
3
Quelle est la complexité temporelle de cette concaténation de chaînes?
d34th4ck3r
@ d34th4ck3r: C'est linéaire.
Nawaz
30

Puisqu'il s'agit de C ++, pourquoi ne pas l'utiliser à la std::stringplace de char*? La concaténation sera triviale:

std::string str = "abc";
str += "another";
Nogard
la source
1
À noter, l'utilisation triviale a un prix non négligeable en ce qui concerne les performances d'exécution. Le pire des cas est celui qui operator+=effectue à la fois une désallocation et une allocation. Les allocations de tas font partie des opérations les plus coûteuses que nous effectuons couramment.
IInspectable le
15

Si vous programmiez en C, en supposant namequ'il s'agit vraiment d'un tableau de longueur fixe comme vous le dites, vous devez faire quelque chose comme ceci:

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

Vous voyez maintenant pourquoi tout le monde recommande std::string?

TonyK
la source
1
Vous ne voyez pas que le gars a posé une question en C ++ et non en C ??
IcyFlame
21
Ne voyez-vous pas que j'ai dit "Si vous programmiez ..."?
TonyK
Ne pensez-vous pas que cette réponse n'est pas pertinente pour cette question?
IcyFlame
9
Je pense que c'est pertinent car "le gars" utilise char au lieu de std :: string. En outre, il montre une manière explicite de concaténer qui n'a pas été montrée dans la réponse la plus votée. Au moins, j'ai appris quelque chose avec.
gvegayon
1
Cela montre également une méthode de concaténation de chaînes sans allocation de mémoire dynamique. Sauf erreur de ma part, l'opérateur std :: string + = nécessite une éventuelle réallocation.
Ashley Duncan
7

Il existe une fonction strcat () de la bibliothèque C portée qui effectuera la concaténation "chaîne de style C" pour vous.

BTW même si C ++ a un tas de fonctions pour traiter les chaînes de style C, il pourrait être avantageux pour vous d'essayer de créer votre propre fonction qui fait cela, quelque chose comme:

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

...puis...

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

... dont le résultat est file_name.txt.

Vous pourriez également être tenté d'écrire le vôtre, operator +mais les surcharges d'opérateur IIRC avec uniquement des pointeurs car les arguments ne sont pas autorisés.

N'oubliez pas non plus que le résultat dans ce cas est alloué dynamiquement, vous pouvez donc appeler delete dessus pour éviter les fuites de mémoire, ou vous pouvez modifier la fonction pour utiliser le tableau de caractères alloué par pile, à condition bien sûr qu'il ait une longueur suffisante.

dtech
la source
Voir mon commentaire sur la réponse d'IcyFlame.
TonyK
3
Il y a aussi une strncat()fonction qui est généralement une meilleure alternative
nogard
@nogard: strncatn'est pas pertinent ici, car nous connaissons déjà la longueur du deuxième paramètre ".txt". Donc ce serait juste strncat(name, ".txt", 4), ce qui ne nous rapporte rien.
TonyK
0

Il est préférable d'utiliser la classe de chaînes C ++ au lieu de l'ancienne chaîne de style C, la vie serait beaucoup plus facile.

si vous avez une chaîne de style ancien existante, vous pouvez convertir en classe de chaîne

    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
la source
0

C ++ 14

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

Réponse à la question:

auto fname = ""s + name + ".txt";
SM
la source
-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
la source