Risposte:
C non ha il supporto per le stringhe di altre lingue. Una stringa in C è solo un puntatore a un array char
che è terminato dal primo carattere null. Non esiste un operatore di concatenazione di stringhe in C.
Utilizzare strcat
per concatenare due stringhe. È possibile utilizzare la seguente funzione per farlo:
#include <stdlib.h>
#include <string.h>
char* concat(const char *s1, const char *s2)
{
char *result = malloc(strlen(s1) + strlen(s2) + 1); // +1 for the null-terminator
// in real code you would check for errors in malloc here
strcpy(result, s1);
strcat(result, s2);
return result;
}
Questo non è il modo più veloce per farlo, ma non dovresti preoccupartene adesso. Si noti che la funzione restituisce un blocco di memoria allocata dell'heap al chiamante e passa la proprietà di quella memoria. È responsabilità del chiamante nei confronti free
della memoria quando non è più necessaria.
Chiamare la funzione in questo modo:
char* s = concat("derp", "herp");
// do things with s
free(s); // deallocate the string
Se ti è capitato di essere disturbato dalle prestazioni, allora dovresti evitare di scansionare ripetutamente i buffer di input alla ricerca del null-terminator.
char* concat(const char *s1, const char *s2)
{
const size_t len1 = strlen(s1);
const size_t len2 = strlen(s2);
char *result = malloc(len1 + len2 + 1); // +1 for the null-terminator
// in real code you would check for errors in malloc here
memcpy(result, s1, len1);
memcpy(result + len1, s2, len2 + 1); // +1 to copy the null-terminator
return result;
}
Se stai pianificando di lavorare molto con le stringhe, allora potresti stare meglio usando un linguaggio diverso che abbia un supporto di prima classe per le stringhe.
stpcpy
, che restituisce un puntatore alla fine della prima stringa:strcpy(stpcpy(result, s1), s2);
David Heffernan ha spiegato il problema nella sua risposta e ho scritto il codice migliorato. Vedi sotto.
Possiamo scrivere un'utile funzione variadica per concatenare qualsiasi numero di stringhe:
#include <stdlib.h> // calloc
#include <stdarg.h> // va_*
#include <string.h> // strlen, strcpy
char* concat(int count, ...)
{
va_list ap;
int i;
// Find required length to store merged string
int len = 1; // room for NULL
va_start(ap, count);
for(i=0 ; i<count ; i++)
len += strlen(va_arg(ap, char*));
va_end(ap);
// Allocate memory to concat strings
char *merged = calloc(sizeof(char),len);
int null_pos = 0;
// Actually concatenate strings
va_start(ap, count);
for(i=0 ; i<count ; i++)
{
char *s = va_arg(ap, char*);
strcpy(merged+null_pos, s);
null_pos += strlen(s);
}
va_end(ap);
return merged;
}
#include <stdio.h> // printf
void println(char *line)
{
printf("%s\n", line);
}
int main(int argc, char* argv[])
{
char *str;
str = concat(0); println(str); free(str);
str = concat(1,"a"); println(str); free(str);
str = concat(2,"a","b"); println(str); free(str);
str = concat(3,"a","b","c"); println(str); free(str);
return 0;
}
Produzione:
// Empty line
a
ab
abc
Si noti che è necessario liberare la memoria allocata quando non è necessaria per evitare perdite di memoria:
char *str = concat(2,"a","b");
println(str);
free(str);
int len
-> size_t len
come size_t
è il tipo giusto per il codice "size". Inoltre // room for NULL
-> // room for null character
NULL
implica il puntatore null.
Presumo che tu ne abbia bisogno per cose una tantum. Presumo che tu sia uno sviluppatore di PC.
Usa la pila, Luke. Usalo ovunque. Non usare mai malloc / free per piccole allocazioni, mai .
#include <string.h>
#include <stdio.h>
#define STR_SIZE 10000
int main()
{
char s1[] = "oppa";
char s2[] = "gangnam";
char s3[] = "style";
{
char result[STR_SIZE] = {0};
snprintf(result, sizeof(result), "%s %s %s", s1, s2, s3);
printf("%s\n", result);
}
}
Se 10 KB per stringa non saranno sufficienti, aggiungi uno zero alla dimensione e non preoccuparti, rilasceranno comunque la memoria dello stack alla fine degli ambiti.
snprintf(result, sizeof result, "%s %s %s", s1, s2, s3);
Si dovrebbe usare strcat
, o meglio, strncat
. Google it (la parola chiave è "concatenare").
strncat()
è una funzione diabolicamente difficile da usare correttamente. Rapidamente, senza consultare il manuale, a quale lunghezza specifichi strncat()
? Se hai detto "la lunghezza del buffer", hai semplicemente dimostrato bene il mio punto. Ha un'interfaccia contro-intuitiva e quando hai abbastanza dati per usarlo in sicurezza, non devi prima usare la funzione - ci sono altre alternative, più veloci ed efficienti (come strcpy()
o memmove()
) che potrebbero essere usate anziché. Praticamente qualunque sia la domanda su "cosa dovrei usare", strncat()
non è la risposta.
Non è possibile aggiungere valori letterali di stringa come quello in C. È necessario creare un buffer di dimensioni di valore letterale stringa + valore letterale stringa due + un byte per carattere di terminazione null e copiare i valori letterali corrispondenti in quel buffer e assicurarsi anche che sia terminato null . Oppure puoi usare funzioni di libreria come strcat
.
Senza estensione GNU:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
const char str1[] = "First";
const char str2[] = "Second";
char *res;
res = malloc(strlen(str1) + strlen(str2) + 1);
if (!res) {
fprintf(stderr, "malloc() failed: insufficient memory!\n");
return EXIT_FAILURE;
}
strcpy(res, str1);
strcat(res, str2);
printf("Result: '%s'\n", res);
free(res);
return EXIT_SUCCESS;
}
In alternativa con estensione GNU:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
const char str1[] = "First";
const char str2[] = "Second";
char *res;
if (-1 == asprintf(&res, "%s%s", str1, str2)) {
fprintf(stderr, "asprintf() failed: insufficient memory!\n");
return EXIT_FAILURE;
}
printf("Result: '%s'\n", res);
free(res);
return EXIT_SUCCESS;
}
#include <string.h>
#include <stdio.h>
int main()
{
int a,l;
char str[50],str1[50],str3[100];
printf("\nEnter a string: ");
scanf("%s",str);
str3[0]='\0';
printf("\nEnter the string which you want to concat with string one: ");
scanf("%s",str1);
strcat(str3,str);
strcat(str3,str1);
printf("\nThe string is %s\n",str3);
}
La concatenazione di due stringhe qualsiasi in C può essere eseguita in almeno 3 modi: -
1) Copiando la stringa 2 alla fine della stringa 1
#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
char str1[MAX],str2[MAX];
int i,j=0;
printf("Input string 1: ");
gets(str1);
printf("\nInput string 2: ");
gets(str2);
for(i=strlen(str1);str2[j]!='\0';i++) //Copying string 2 to the end of string 1
{
str1[i]=str2[j];
j++;
}
str1[i]='\0';
printf("\nConcatenated string: ");
puts(str1);
return 0;
}
2) Copiando la stringa 1 e la stringa 2 nella stringa 3
#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
char str1[MAX],str2[MAX],str3[MAX];
int i,j=0,count=0;
printf("Input string 1: ");
gets(str1);
printf("\nInput string 2: ");
gets(str2);
for(i=0;str1[i]!='\0';i++) //Copying string 1 to string 3
{
str3[i]=str1[i];
count++;
}
for(i=count;str2[j]!='\0';i++) //Copying string 2 to the end of string 3
{
str3[i]=str2[j];
j++;
}
str3[i]='\0';
printf("\nConcatenated string : ");
puts(str3);
return 0;
}
3) Usando la funzione strcat ()
#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
char str1[MAX],str2[MAX];
printf("Input string 1: ");
gets(str1);
printf("\nInput string 2: ");
gets(str2);
strcat(str1,str2); //strcat() function
printf("\nConcatenated string : ");
puts(str1);
return 0;
}
In C, in realtà non hai stringhe, come oggetto generico di prima classe. Devi gestirli come matrici di personaggi, il che significa che devi determinare come vorresti gestire le tue matrici. Un modo è quello di variabili normali, ad esempio posizionate in pila. Un altro modo è di allocarli dinamicamente usando malloc
.
Una volta ordinato, puoi copiare il contenuto di un array in un altro, per concatenare due stringhe usando strcpy
o strcat
.
Detto questo, C ha il concetto di "letterali stringa", che sono stringhe conosciute al momento della compilazione. Se utilizzati, saranno una matrice di caratteri collocata nella memoria di sola lettura. È, tuttavia, possibile concatenare due letterali di stringa scrivendoli uno accanto all'altro, come in "foo" "bar"
, che creerà la stringa letterale "foobar".
usando memcpy
char *str1="hello";
char *str2=" world";
char *str3;
str3=(char *) malloc (11 *sizeof(char));
memcpy(str3,str1,5);
memcpy(str3+strlen(str1),str2,6);
printf("%s + %s = %s",str1,str2,str3);
free(str3);
return memcpy(result, s1, len1);
. Sebbene sia una micro-ottimizzazione o almeno un po 'di golf del codice, tali potenziali miglioramenti sulle operazioni di base delle stringhe possono avere un valore dato il loro elevato utilizzo.