Come posso concatenare due stringhe in C?


141

Come faccio ad aggiungere due stringhe?

Ho provato name = "derp" + "herp";, ma ho ricevuto un errore:

L'espressione deve avere tipo integrale o enum

Risposte:


184

C non ha il supporto per le stringhe di altre lingue. Una stringa in C è solo un puntatore a un array charche è terminato dal primo carattere null. Non esiste un operatore di concatenazione di stringhe in C.

Utilizzare strcatper 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 freedella 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.


1
Piccolo bit: il codice potrebbe eseguire l'ultima copia della prima parte della stringa e quindi 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.
chux - Ripristina Monica il

2
Piccolo miglioramento delle prestazioni della prima versione che utilizza stpcpy, che restituisce un puntatore alla fine della prima stringa:strcpy(stpcpy(result, s1), s2);
Daniel

17
#include <stdio.h>

int main(){
    char name[] =  "derp" "herp";
    printf("\"%s\"\n", name);//"derpherp"
    return 0;
}

1
Funziona anche con le macro in c, che vale la pena notare
Abe Fehr,

15

David Heffernan ha spiegato il problema nella sua risposta e ho scritto il codice migliorato. Vedi sotto.

Una funzione generica

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

uso

#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

Pulire

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

3
Gli argomenti da chiamare sono arretrati. Dovrebbero essere conteggiati quindi le dimensioni. Puoi cavartela qui grazie all'identità moltiplicativa, poiché sizeof (char) è definito come 1.
Andy,

Considera int len-> size_t lencome size_tè il tipo giusto per il codice "size". Inoltre // room for NULL-> // room for null character NULLimplica il puntatore null.
chux - Ripristina Monica il

10

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.


1
Ciò sarebbe più chiaramente espresso comesnprintf(result, sizeof result, "%s %s %s", s1, s2, s3);
MM

8

Si dovrebbe usare strcat, o meglio, strncat. Google it (la parola chiave è "concatenare").


8
Attenzione: 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.
Jonathan Leffler,

5

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.


3

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

Vedi malloc , gratuito e asprintf per maggiori dettagli.


2
#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);
}

2

Stringhe concatenate

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

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 strcpyo 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".


0

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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.