Wie verkette ich zwei Zeichenfolgen in C?

141

Wie füge ich zwei Zeichenfolgen hinzu?

Ich habe es versucht name = "derp" + "herp";, aber ich habe eine Fehlermeldung erhalten:

Der Ausdruck muss einen Integral- oder Aufzählungstyp haben

Levi H.
quelle

Antworten:

184

C unterstützt keine Zeichenfolgen, die einige andere Sprachen haben. Eine Zeichenfolge in C ist nur ein Zeiger auf ein Array char, das durch das erste Nullzeichen abgeschlossen wird. In C gibt es keinen String-Verkettungsoperator.

Verwenden Sie strcatdiese Option, um zwei Zeichenfolgen zu verketten. Sie können die folgende Funktion verwenden, um dies zu tun:

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

Dies ist nicht der schnellste Weg, aber darüber sollten Sie sich jetzt keine Sorgen machen. Beachten Sie, dass die Funktion einen Block des Heap-zugewiesenen Speichers an den Aufrufer zurückgibt und den Besitz dieses Speichers weitergibt. Es liegt in der Verantwortung des Anrufers, freeden Speicher zu speichern, wenn er nicht mehr benötigt wird.

Rufen Sie die Funktion folgendermaßen auf:

char* s = concat("derp", "herp");
// do things with s
free(s); // deallocate the string

Wenn Sie zufällig von der Leistung gestört werden, sollten Sie vermeiden, die Eingabepuffer wiederholt nach dem Nullterminator zu durchsuchen.

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

Wenn Sie vorhaben, viel mit Zeichenfolgen zu arbeiten, ist es möglicherweise besser, eine andere Sprache zu verwenden, die erstklassige Unterstützung für Zeichenfolgen bietet.

David Heffernan
quelle
1
Kleines Bit: Code könnte die Kopie des ersten Teils der Zeichenfolge zuletzt und dann ausführen return memcpy(result, s1, len1);. Obwohl es sich um eine Mikrooptimierung oder zumindest ein bisschen Code-Golf handelt, können solche potenziellen Verbesserungen bei grundlegenden Saitenoperationen aufgrund ihrer hohen Verwendung von Wert sein.
chux
1
Kleine Leistungsverbesserung der ersten Version mit stpcpy, die einen Zeiger auf das Ende der ersten Zeichenfolge zurückgibt:strcpy(stpcpy(result, s1), s2);
Daniel
17
#include <stdio.h>

int main(){
    char name[] =  "derp" "herp";
    printf("\"%s\"\n", name);//"derpherp"
    return 0;
}
BLUEPIXY
quelle
1
Es funktioniert auch für Makros in c, was erwähnenswert ist
Abe Fehr
15

David Heffernan erklärte das Problem in seiner Antwort, und ich schrieb den verbesserten Code. Siehe unten.

Eine generische Funktion

Wir können eine nützliche Variadic-Funktion schreiben, um eine beliebige Anzahl von Zeichenfolgen zu verketten:

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

Verwendung

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

Ausgabe:

  // Empty line
a
ab
abc

Aufräumen

Beachten Sie, dass Sie den zugewiesenen Speicher freigeben sollten, wenn er nicht mehr benötigt wird, um Speicherlecks zu vermeiden:

char *str = concat(2,"a","b");
println(str);
free(str);
mmdemirbas
quelle
3
Die Argumente für calloc sind rückwärts. Sie sollten dann Größe zählen. Sie kommen hier dank der multiplikativen Identität davon, da sizeof (char) als 1 definiert ist.
Andy
Betrachten Sie int len-> size_t lenals size_tden richtigen Typ für "Größen" -Code. Auch // room for NULL-> // room for null character NULLimpliziert den Nullzeiger.
chux - Monica
9

Ich gehe davon aus, dass Sie es für einmalige Dinge brauchen. Ich gehe davon aus, dass Sie ein PC-Entwickler sind.

Benutze den Stapel, Luke. Verwenden Sie es überall. Verwenden Sie malloc / free niemals für kleine Zuweisungen .

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

Wenn 10 KB pro Zeichenfolge nicht ausreichen, fügen Sie der Größe eine Null hinzu und kümmern Sie sich nicht darum. Sie geben ihren Stapelspeicher ohnehin am Ende des Bereichs frei.


quelle
1
Dies würde deutlicher ausgedrückt alssnprintf(result, sizeof result, "%s %s %s", s1, s2, s3);
MM
8

Sie sollten verwenden strcatoder besser strncat. Google it (das Schlüsselwort ist "verketten").

orlp
quelle
8
Achtung: Es strncat()ist eine teuflisch schwierige Funktion, sie richtig zu verwenden. Welche Länge geben Sie schnell an, ohne das Handbuch zu lesen strncat()? Wenn Sie "die Länge des Puffers" sagten, haben Sie meinen Standpunkt nur gut demonstriert. Es verfügt über eine kontraintuitive Benutzeroberfläche, und wenn Sie über genügend Daten verfügen, um sie sicher zu verwenden, müssen Sie die Funktion erst gar nicht verwenden. Es gibt andere, schnellere und effizientere Alternativen (wie strcpy()oder memmove()), die verwendet werden könnten stattdessen. Was auch immer die Frage ist, was ich verwenden soll, strncat()ist nicht die Antwort.
Jonathan Leffler
5

Sie können in C keine solchen Zeichenfolgenliterale hinzufügen. Sie müssen einen Puffer mit der Größe von Zeichenfolgenliteral eins + Zeichenfolgenliteral zwei + einem Byte für das Nullabschlusszeichen erstellen und die entsprechenden Literale in diesen Puffer kopieren und sicherstellen, dass er mit Null abgeschlossen ist . Oder Sie können Bibliotheksfunktionen wie verwenden strcat.

Mahesh
quelle
3

Ohne GNU-Erweiterung:

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

Alternativ mit GNU-Erweiterung:

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

Weitere Informationen finden Sie unter malloc , free und asprintf .

Peter Mortensen
quelle
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);
}
user2870383
quelle
2

Strings verketten

Das Verketten von zwei beliebigen Zeichenfolgen in C kann auf mindestens drei Arten erfolgen:

1) Durch Kopieren von Zeichenfolge 2 an das Ende von Zeichenfolge 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) Durch Kopieren von String 1 und String 2 in String 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) Mit der Funktion 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;
}
Paurav Shah
quelle
0

In C haben Sie als generisches erstklassiges Objekt nicht wirklich Zeichenfolgen. Sie müssen sie als Arrays von Zeichen verwalten, was bedeutet, dass Sie festlegen müssen, wie Sie Ihre Arrays verwalten möchten. Eine Möglichkeit sind normale Variablen, z. B. auf dem Stapel. Eine andere Möglichkeit besteht darin, sie mithilfe von dynamisch zuzuweisen malloc.

Sobald Sie dies sortiert haben, können Sie den Inhalt eines Arrays in ein anderes kopieren, um zwei Zeichenfolgen mit strcpyoder zu verketten strcat.

Allerdings hat C das Konzept von "String-Literalen", die zur Kompilierungszeit bekannte Strings sind. Bei Verwendung handelt es sich um ein Zeichenarray, das im Nur-Lese-Speicher abgelegt wird. Es ist jedoch möglich, zwei Zeichenfolgenliterale zu verketten, indem Sie sie wie in nebeneinander schreiben "foo" "bar", wodurch das Zeichenfolgenliteral "foobar" erstellt wird.

Lindydancer
quelle
0

mit 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);
Khalegh Salehi
quelle