¿Cómo concateno dos cadenas en C?

141

¿Cómo agrego dos cadenas?

Lo intenté name = "derp" + "herp";, pero recibí un error:

La expresión debe tener un tipo integral o enum

Levi H
fuente

Respuestas:

184

C no tiene el soporte para cadenas que tienen otros lenguajes. Una cadena en C es solo un puntero a una matriz charque termina con el primer carácter nulo. No hay operador de concatenación de cadenas en C.

Use strcatpara concatenar dos cadenas. Puede usar la siguiente función para hacerlo:

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

Esta no es la forma más rápida de hacerlo, pero no debería preocuparse por eso ahora. Tenga en cuenta que la función devuelve un bloque de memoria asignada de almacenamiento dinámico al llamante y transfiere la propiedad de esa memoria. Es responsabilidad de la persona que llama freela memoria cuando ya no se necesita.

Llame a la función así:

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

Si le molesta el rendimiento, entonces querrá evitar escanear repetidamente las memorias intermedias de entrada en busca del terminador nulo.

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

Si está planeando hacer mucho trabajo con cadenas, entonces es mejor que use un lenguaje diferente que tenga soporte de primera clase para cadenas.

David Heffernan
fuente
1
Pequeño bit: el código podría hacer la copia de la primera parte de la cadena al final y luego return memcpy(result, s1, len1);. Aunque una microoptimización o al menos un poco de código de golf, tales mejoras potenciales en las operaciones básicas de cadena pueden tener valor dado su alto uso.
chux - Restablece a Mónica el
2
Pequeña mejora de rendimiento de la primera versión que usa stpcpy, que devuelve un puntero al final de la primera cadena:strcpy(stpcpy(result, s1), s2);
Daniel
17
#include <stdio.h>

int main(){
    char name[] =  "derp" "herp";
    printf("\"%s\"\n", name);//"derpherp"
    return 0;
}
BLUEPIXY
fuente
1
También funciona para macros en c, que vale la pena señalar
Abe Fehr,
15

David Heffernan explicó el problema en su respuesta y yo escribí el código mejorado. Vea abajo.

Una función genérica

Podemos escribir una función variada útil para concatenar cualquier número de cadenas:

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

Salida:

  // Empty line
a
ab
abc

Limpiar

Tenga en cuenta que debe liberar la memoria asignada cuando sea innecesaria para evitar pérdidas de memoria:

char *str = concat(2,"a","b");
println(str);
free(str);
mmdemirbas
fuente
3
Los argumentos para calloc son al revés. Deben ser contados y luego de tamaño. Te saldrás con la tuya aquí gracias a la identidad multiplicativa, ya que sizeof (char) se define como 1.
Andy
Considere int len-> size_t lencomo size_tes el tipo correcto para el código de "tamaño". También // room for NULL-> // room for null character NULLimplica el puntero nulo.
chux - Restablece a Mónica el
9

Asumiré que lo necesitas para cosas únicas. Asumiré que eres un desarrollador de PC.

Usa la pila, Luke. Úselo en todas partes. No use malloc / free para pequeñas asignaciones, nunca .

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

Si 10 KB por cadena no son suficientes, agregue un cero al tamaño y no se moleste, de todos modos liberarán su memoria de pila al final de los ámbitos.


fuente
1
Esto se expresaría más claramente comosnprintf(result, sizeof result, "%s %s %s", s1, s2, s3);
MM
8

Deberías usar strcat, o mejor strncat,. Google (la palabra clave es "concatenación").

orlp
fuente
8
Cuidado: strncat()es una función endiabladamente difícil de usar correctamente. Rápidamente, sin mirar el manual, ¿a qué longitud especificas strncat()? Si dijiste "la longitud del búfer", acabas de demostrar mi punto muy bien. Tiene una interfaz contra-intuitiva y cuando tiene suficientes datos para usarla de manera segura, no necesita usar la función en primer lugar; existen otras alternativas más rápidas y más eficientes (como strcpy()o memmove()) que podrían usarse en lugar. Cualquiera que sea la pregunta de "qué debo usar", strncat()no es la respuesta.
Jonathan Leffler
5

No puede agregar literales de cadena como ese en C. Debe crear un búfer de tamaño de literal de cadena uno + literal de cadena dos + un byte para el carácter de terminación nula y copiar los literales correspondientes a ese búfer y también asegurarse de que sea nulo terminado . O puede usar funciones de biblioteca como strcat.

Mahesh
fuente
3

Sin extensión 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;
}

Alternativamente con la extensión 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;
}

Vea malloc , gratis y asprintf para más detalles.

Peter Mortensen
fuente
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);
}
usuario2870383
fuente
2

Concatenar cadenas

La concatenación de dos cadenas en C se puede hacer de al menos 3 formas: -

1) Al copiar la cadena 2 al final de la cadena 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) Al copiar la cadena 1 y la cadena 2 a la cadena 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) Al usar la función 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
fuente
0

En C, realmente no tiene cadenas, como un objeto genérico de primera clase. Debe administrarlos como matrices de caracteres, lo que significa que debe determinar cómo desea administrar sus matrices. Una forma es a las variables normales, por ejemplo, colocadas en la pila. Otra forma es asignarlos dinámicamente usando malloc.

Una vez que haya ordenado eso, puede copiar el contenido de una matriz a otra, para concatenar dos cadenas usando strcpyo strcat.

Dicho esto, C tiene el concepto de "literales de cadena", que son cadenas conocidas en tiempo de compilación. Cuando se usen, serán una matriz de caracteres colocada en la memoria de solo lectura. Sin embargo, es posible concatenar dos literales de cadena escribiéndolos uno al lado del otro, como en "foo" "bar", lo que creará el literal de cadena "foobar".

Lindydancer
fuente
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);
Khalegh Salehi
fuente