Como concatenar duas seqüências de caracteres em C?

141

Como adiciono duas strings?

Eu tentei name = "derp" + "herp";, mas recebi um erro:

A expressão deve ter tipo integral ou enum

Levi H
fonte

Respostas:

184

C não tem suporte para strings que alguns outros idiomas possuem. Uma string em C é apenas um ponteiro para uma matriz charterminada pelo primeiro caractere nulo. Não há operador de concatenação de cadeias em C.

Use strcatpara concatenar duas strings. Você pode usar a seguinte função para fazer isso:

#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 não é a maneira mais rápida de fazer isso, mas você não deve se preocupar com isso agora. Observe que a função retorna um bloco de memória alocada ao heap ao chamador e passa a propriedade dessa memória. É de responsabilidade do chamador freea memória quando ela não é mais necessária.

Chame a função assim:

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

Se você se incomodou com o desempenho, evitaria varrer repetidamente os buffers de entrada procurando o 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;
}

Se você planeja trabalhar muito com strings, pode ser melhor usar um idioma diferente que tenha suporte de primeira classe para strings.

David Heffernan
fonte
1
Pouco: código poderia fazer a cópia da primeira parte da string por último e depois return memcpy(result, s1, len1);. Embora uma micro-otimização ou pelo menos um pouco de código de golfe, essas melhorias em potencial nas operações básicas de cadeia podem ter valor devido ao seu alto uso.
chux - Restabelece Monica 9/16
2
Pequena melhoria no desempenho da primeira versão usando stpcpy, que retorna um ponteiro para o final da primeira string:strcpy(stpcpy(result, s1), s2);
Daniel
17
#include <stdio.h>

int main(){
    char name[] =  "derp" "herp";
    printf("\"%s\"\n", name);//"derpherp"
    return 0;
}
BLUEPIXY
fonte
1
Ele também funciona para macros em C, que é digno de nota
Abe Fehr
15

David Heffernan explicou o problema em sua resposta e eu escrevi o código aprimorado. Ver abaixo.

Uma função genérica

Podemos escrever uma função variadic útil para concatenar qualquer número de strings:

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

Resultado:

  // Empty line
a
ab
abc

Limpar

Observe que você deve liberar a memória alocada quando ela for desnecessária para evitar vazamentos de memória:

char *str = concat(2,"a","b");
println(str);
free(str);
mmdemirbas
fonte
3
Os argumentos para calloc são invertidos. Eles devem ser contados e tamanho. Você se sai bem aqui, graças à identidade multiplicativa, já que sizeof (char) é definido como 1.
Andy
Considere int len-> size_t lencomo size_té o tipo certo para o código "size". Também // room for NULL-> // room for null character NULLimplica o ponteiro nulo.
chux - Restabelece Monica
9

Presumo que você precise para coisas pontuais. Eu assumo que você é um desenvolvedor de PC.

Use a pilha, Luke. Use-o em qualquer lugar. Não use malloc / livre para pequenas alocações, 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);
  }
}

Se 10 KB por string não forem suficientes, adicione zero ao tamanho e não se preocupe - eles liberarão sua memória de pilha no final dos escopos de qualquer maneira.


fonte
1
Isso seria expresso com mais clareza comosnprintf(result, sizeof result, "%s %s %s", s1, s2, s3);
MM
8

Você deveria usar strcat, ou melhor strncat,. Pesquise no Google (a palavra-chave é "concatenar").

orlp
fonte
8
Cuidado: strncat()é uma função extremamente difícil de usar corretamente. Rapidamente, sem olhar para o manual, qual o comprimento especificado strncat()? Se você disse "o tamanho do buffer", acabou de demonstrar meu ponto de vista. Possui uma interface contra-intuitiva e, quando você tem dados suficientes para usá-los com segurança, não precisa usar a função em primeiro lugar - existem outras alternativas, mais rápidas e mais eficientes (como strcpy()ou memmove()) que podem ser usadas em vez de. Praticamente qualquer que seja a pergunta "o que devo usar", strncat()não é a resposta.
Jonathan Leffler
5

Você não pode adicionar literais de string como esse em C. Você deve criar um buffer de tamanho da string literal um + string literal dois + um byte para caractere de terminação nulo e copiar os literais correspondentes para esse buffer e também garantir que ele seja terminado nulo . Ou você pode usar funções de biblioteca como strcat.

Mahesh
fonte
3

Sem extensão 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;
}

Como alternativa com a extensão 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;
}

Veja malloc , free e asprintf para mais detalhes.

Peter Mortensen
fonte
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
fonte
2

Concatenar strings

A concatenação de duas seqüências de caracteres em C pode ser feita de pelo menos três maneiras: -

1) Copiando a sequência 2 para o final da sequência 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 a sequência 1 e a sequência 2 para a sequência 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 a função 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
fonte
0

Em C, você realmente não possui seqüências de caracteres, como um objeto genérico de primeira classe. É necessário gerenciá-los como matrizes de caracteres, o que significa que é necessário determinar como você deseja gerenciar suas matrizes. Uma maneira é obter variáveis ​​normais, por exemplo, colocadas na pilha. Outra maneira é alocá-los dinamicamente usando malloc.

Depois de ordenar isso, você pode copiar o conteúdo de uma matriz para outra, para concatenar duas cadeias usando strcpyoustrcat .

Dito isto, C tem o conceito de "literais de strings", que são strings conhecidas em tempo de compilação. Quando usados, eles serão uma matriz de caracteres colocada na memória somente leitura. No entanto, é possível concatenar dois literais de cadeia de caracteres, escrevendo-os um ao lado do outro, como em "foo" "bar", o que criará a cadeia de caracteres literal "foobar".

Lindydancer
fonte
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
fonte