2010-01-03 22 views
85

ho bisogno di concatenare due caratteri const come questi:const char * concatenazione

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

Come potrei andare a fare che?

Ho passato questi char* da una libreria di terze parti con un'interfaccia C, quindi non posso semplicemente usare std::string.

+5

I Sono confuso - l'interrogante originale ha scritto il tag "C++" - poi qualcun altro lo ha rimosso. Qual è lo stato delle cose per questa domanda? È permesso il codice C++? –

+0

@Johannes: Questa è una domanda migliore xD. –

+0

Nota anche che la domanda originale NON si riferiva a C - Ho rimosso quel tag. –

risposta

75

Nel tuo esempio uno e due sono puntatori char, puntando a char costanti. Non è possibile modificare le costanti di carattere puntate da questi puntatori. Quindi, ad esempio:

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

non funziona. Invece dovresti avere una variabile separata (array di caratteri) per contenere il risultato. Qualcosa di simile a questo:

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

Ha! Avevo usato strcpy e strcat e non funzionava, ma quello era l'unico modo in cui non l'ho provato, grazie! –

+2

perché l'hai taggato in C++? ... –

+0

@Anthoni: Prego :) – codaddict

27

Se si utilizza C++, perché non si utilizza std::string invece di stringhe in stile C?

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

std::string three= one+two; 

Se è necessario passare questa stringa a un C-funzione, è sufficiente passare three.c_str()

+5

Perché sto usando una libreria codificata in C quindi le funzioni restituiscono const char * –

+4

Quindi il tag è fuorviante. –

+3

Bene, lo sto codificando in Cpp. –

17

Utilizzando std::string:

#include <string> 

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

La seconda chiamata al costruttore esplicita non è necessaria – sellibitze

5

Prima di tutto, è necessario creare un po 'di spazio di memoria dinamica. Quindi puoi semplicemente inserire le due stringhe in esso. Oppure puoi usare la classe "string" C++. Il modo vecchia scuola 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); 

Nuova C++ modo

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

perché hai bisogno di memoria dinamica? –

+4

-1 per me, prima con C-way devi usare malloc e gratis. Quindi, anche se fai qualcosa di nuovo, dovrebbe essere delete [] e non cancellare. – Naveen

+0

La libreria che sto usando è codificata in C non C++, quindi tutte le funzioni restituiscono const char * not string. –

57

Il modo C:

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

Il modo C++:

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

La fase di compilazione modo:

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

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

Un esempio:

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

Ma a meno che specificamente non si vuole o non può utilizzare la libreria standard C++, utilizzando std::string è probabilmente più sicuro.

+1

Se l'OP non può usare C++, non può usare 'new'. E se può usarlo, dovrebbe usare 'std :: string', come dici tu. –

3

È possibile utilizzare strstream. È formalmente deprecato, ma è comunque un ottimo strumento se hai bisogno di lavorare con le stringhe C, penso.

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

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

Questo scriverà one e poi two nel flusso, e aggiungere una terminazione \0 utilizzando std::ends. Nel caso in cui entrambe le stringhe potrebbero finire per scrivere esattamente 99 caratteri - quindi non lasciare spazio scrivendo \0 - ne scriviamo uno manualmente nell'ultima posizione.

+0

La deprecazione non dovrebbe importare troppo. Anche se viene rimosso da una versione futura dello standard, non è tanto il lavoro da ri-implementare nel proprio spazio dei nomi. –

+0

@Steve, infatti :) E anche scrivere il proprio output di indirizzamento 'streambuf' su un buffer di caratteri usato con' ostream' non è troppo difficile. –

5

Sembra che si stia utilizzando C++ con una libreria C e pertanto è necessario lavorare con const char *.

Suggerisco avvolgendo quelle const char * in std::string:

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

che ne dici di un esempio di c_str()? – sellibitze

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

Aggiornamento: cambiato string total = string(one) + string(two); per string total(string(one) + two); per motivi di prestazioni (evita la costruzione di stringa di due e totale stringa temporanea)

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

non molto efficace in velocità, non una bella soluzione – Iburidu

+0

@iburidu hai misurato? Che dire delle situazioni in cui la sicurezza supera la prestazione? (Sono situazioni comuni) – Sqeaky

+3

@Sqeaky Non ci sono assolutamente situazioni in cui questo sia più sicuro di qualsiasi altra soluzione, ma è SEMPRE più lento di una soluzione di compilazione, richiamando il comportamento di runtime e quasi certamente richiamando l'allocazione di memoria. – Alice

0

Collegamento a due puntatori char costante senza utilizzare il comando strcpy nella allocazione dinamica della 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

Se non si conosce la dimensione delle stringhe, si può fare qualcosa di simile:

#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; 
} 
Problemi correlati