Как объединить две строки в C? - PullRequest
119 голосов
/ 11 декабря 2011

Как добавить две строки?

Я пытался name = "derp" + "herp";, но получил ошибку:

Выражение должно иметь целочисленный тип или тип enum

Ответы [ 10 ]

149 голосов
/ 11 декабря 2011

C не поддерживает строки, которые есть в некоторых других языках. Строка в C - это просто указатель на массив char, который заканчивается первым нулевым символом. В C. нет оператора конкатенации строк *

Используйте strcat для объединения двух строк. Вы можете использовать следующую функцию:

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

Это не самый быстрый способ сделать это, но вы не должны беспокоиться об этом сейчас. Обратите внимание, что функция возвращает блок памяти, выделенной из кучи, вызывающей стороне и передает владение этой памятью. Вызывающий абонент обязан free памяти, когда он больше не нужен.

Вызовите функцию следующим образом:

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

Если вам действительно не понравилась производительность, вам следует избегать повторного сканирования входных буферов в поисках нулевого терминатора.

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

Если вы планируете много работать со строками, то вам лучше использовать другой язык, который поддерживает строки первого класса.

16 голосов
/ 11 декабря 2011
#include <stdio.h>

int main(){
    char name[] =  "derp" "herp";
    printf("\"%s\"\n", name);//"derpherp"
    return 0;
}
12 голосов
/ 09 июля 2012

Дэвид Хеффернан объяснил проблему в своем ответе, и я написал улучшенный код. Смотри ниже.

Общая функция

Мы можем написать полезную переменную функцию для объединения любого числа строк:

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

Выход:

  // Empty line
a
ab
abc

Очистка

Обратите внимание, что вы должны освободить выделенную память, когда она становится ненужной, чтобы избежать утечек памяти:

char *str = concat(2,"a","b");
println(str);
free(str);
8 голосов
/ 11 декабря 2011

Вы должны использовать strcat или лучше strncat.Google это (ключевое слово "сцепление").

6 голосов
/ 26 июня 2015

Полагаю, вам это нужно для разовых вещей. Я предполагаю, что вы разработчик ПК.

Используйте Стек, Люк. Используйте это везде. Не используйте malloc / free для небольших выделений, ever .

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

Если 10 КБ на строку не будет достаточно, добавьте ноль к размеру и не беспокойтесь, - они все равно освободят свою память стека в конце областей.

5 голосов
/ 11 декабря 2011

Вы не можете добавить строковые литералы, подобные этим в C. Вы должны создать буфер размером строковый литерал один + строковый литерал два + байт для нулевого символа завершения и скопировать соответствующие литералы в этот буфер а также убедитесь, что он завершен Или вы можете использовать библиотечные функции, такие как strcat.

3 голосов
/ 11 декабря 2011

Без расширения 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;
}

В качестве альтернативы с расширением 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;
}

Подробнее см. malloc , free и asprintf .

2 голосов
/ 05 августа 2018

Конкатенация строк

Объединение любых двух строк в C может быть сделано по крайней мере 3 способами: -

1) Копируя строку 2 в конец строки 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) Путем копирования строки 1 и строки 2 в строку 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) С помощью функции 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;
}
2 голосов
/ 11 октября 2013
#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);
}
0 голосов
/ 11 декабря 2011

В C вы на самом деле не имеете строк, как универсальный первоклассный объект.Вы должны управлять ими как массивами символов, что означает, что вы должны определить, как вы хотели бы управлять своими массивами.Одним из способов является нормальные переменные, например, помещенные в стек.Другой способ - динамически распределить их, используя malloc.

. После сортировки вы можете скопировать содержимое одного массива в другой, чтобы объединить две строки, используя strcpy или strcat. * 1006.*

Сказав это, в C действительно есть понятие "строковые литералы", которые являются строками, известными во время компиляции.При использовании они будут символьным массивом, помещенным в постоянную память.Однако можно объединить два строковых литерала, написав их рядом друг с другом, как в "foo" "bar", что создаст строковый литерал "foobar".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...