Wie verkette ich zwei Strings in C ++?

100

Ich habe eine private Klassenvariable, char name[10]zu der ich die .txtErweiterung hinzufügen möchte, damit ich die im Verzeichnis vorhandene Datei öffnen kann.

Wie gehe ich vor?

Es ist vorzuziehen, eine neue Zeichenfolgenvariable zu erstellen, die die verkettete Zeichenfolge enthält.

Slashr
quelle

Antworten:

160

Verwenden Sie zunächst nicht char*oder char[N]. Verwenden Sie std::string, dann wird alles andere so einfach!

Beispiele,

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

Einfach, nicht wahr?

Wenn Sie char const *aus irgendeinem Grund etwas benötigen , z. B. wenn Sie an eine Funktion übergeben möchten, können Sie dies tun:

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

Angenommen, diese Funktion wird deklariert als:

some_c_api(char const *input, size_t length);

Entdecken std::stringSie sich von hier aus:

Hoffentlich hilft das.

Nawaz
quelle
3
Was ist die zeitliche Komplexität dieser Zeichenfolgenverkettung?
d34th4ck3r
@ d34th4ck3r: Es ist linear.
Nawaz
30

Da es C ++ ist, warum nicht std::stringstatt verwenden char*? Verkettung wird trivial sein:

std::string str = "abc";
str += "another";
Nogard
quelle
1
Bemerkenswert ist, dass die triviale Verwendung mit einem nicht trivialen Preisschild in Bezug auf die Laufzeitleistung verbunden ist. Der schlimmste Fall ist, dass operator+=sowohl eine Freigabe als auch eine Zuweisung durchgeführt wird. Heap-Zuweisungen gehören zu den teuersten Vorgängen, die wir normalerweise ausführen.
Unsichtbarer
15

Wenn Sie in C programmiert haben und davon ausgehen, dass es sich nametatsächlich um ein Array mit fester Länge handelt, wie Sie sagen, müssen Sie Folgendes tun:

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

Sie sehen jetzt, warum jeder empfiehlt std::string?

TonyK
quelle
1
Kannst du nicht sehen, dass der Typ eine Frage in C ++ und nicht in C gestellt hat?
IcyFlame
21
Kannst du nicht sehen, dass ich sagte "Wenn du programmierst ..."?
TonyK
Denken Sie nicht, dass diese Antwort für diese Frage irrelevant ist?
IcyFlame
9
Ich denke, das ist relevant, da "der Typ" char anstelle von std :: string verwendet. Darüber hinaus zeigt es eine explizite Art der Verkettung, die in der am häufigsten gewählten Antwort nicht gezeigt wurde. Zumindest habe ich etwas damit gelernt.
Gvegayon
1
Dies zeigt auch eine Methode zum Durchführen einer Zeichenfolgenverkettung ohne dynamische Speicherzuweisung. Sofern ich mich nicht irre, erfordert der std :: string-Operator + = eine mögliche Neuzuweisung.
Ashley Duncan
7

Es gibt eine strcat () - Funktion aus der portierten C-Bibliothek, die die Verkettung von "C-Stil-Zeichenfolgen" für Sie übernimmt.

Übrigens, obwohl C ++ eine Reihe von Funktionen für den Umgang mit Zeichenfolgen im C-Stil hat, könnte es für Sie von Vorteil sein, wenn Sie versuchen, eine eigene Funktion zu entwickeln, die dies tut, etwa:

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

...und dann...

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

... das Ergebnis davon ist file_name.txt.

Sie könnten auch versucht sein, Ihre eigenen zu schreiben, operator +jedoch werden IIRC-Operatoren nur mit Zeigern überladen, da Argumente nicht zulässig sind.

Vergessen Sie auch nicht, dass das Ergebnis in diesem Fall dynamisch zugewiesen wird. Sie können daher delete aufrufen, um Speicherverluste zu vermeiden, oder Sie können die Funktion so ändern, dass ein vom Stapel zugewiesenes Zeichenarray verwendet wird, vorausgesetzt, es hat natürlich eine ausreichende Länge.

dtech
quelle
Siehe meinen Kommentar zur Antwort von IcyFlame.
TonyK
3
Es gibt auch eine strncat()Funktion, die normalerweise eine bessere Alternative ist
Nogard
@nogard: strncatist hier irrelevant, da wir die Länge des zweiten Parameters bereits kennen ".txt". So wäre es einfach strncat(name, ".txt", 4), was uns nichts bringt.
TonyK
0

Es ist besser, eine C ++ - Zeichenfolgenklasse anstelle einer alten C-Zeichenfolge zu verwenden. Das Leben wäre viel einfacher.

Wenn Sie eine Zeichenfolge im alten Stil haben, können Sie diese in eine Zeichenfolgenklasse umwandeln

    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
quelle
0

C ++ 14

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

Antwort auf die Frage:

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