Как добавить две строки?
Я попробовал name = "derp" + "herp";
, но у меня ошибка:
Выражение должно иметь целочисленный или перечисляемый тип
Ответы:
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;
}
Если вы планируете много работать со строками, возможно, вам будет лучше использовать другой язык, который имеет первоклассную поддержку строк.
stpcpy
, которая возвращает указатель на конец первой строки:strcpy(stpcpy(result, s1), s2);
Дэвид Хеффернан объяснил проблему в своем ответе, и я написал улучшенный код. Увидеть ниже.
Мы можем написать полезную вариативную функцию для объединения любого количества строк:
#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);
int len
-> , size_t len
как size_t
это правильный тип для «размер» кода. Также // room for NULL
-> // room for null character
NULL
подразумевает нулевой указатель.
Я предполагаю, что он вам понадобится для разовых вещей. Я предполагаю, что вы разработчик ПК.
Используйте стек, Люк. Используйте его везде. Не используйте таНос / бесплатно для небольших распределений, когда - либо .
#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 КБ на строку будет недостаточно, добавьте к размеру ноль и не беспокойтесь, - они все равно освободят свою стековую память в конце областей видимости.
snprintf(result, sizeof result, "%s %s %s", s1, s2, s3);
Вы должны использовать strcat
, или лучше, strncat
. Погуглите (ключевое слово "объединение").
strncat()
это чертовски сложная функция для правильного использования. Какую длину вы указываете быстро, не глядя в инструкции strncat()
? Если вы сказали «длина буфера», вы просто хорошо продемонстрировали мою точку зрения. Он имеет интуитивно понятный интерфейс, и когда у вас достаточно данных для его безопасного использования, вам не нужно использовать эту функцию в первую очередь - есть другие, более быстрые и более эффективные альтернативы (например, strcpy()
или memmove()
), которые можно использовать вместо. Практически независимо от того, «что мне использовать», strncat()
это не ответ.
Вы не можете добавлять строковые литералы, подобные этому, в C. Вам необходимо создать буфер размером строкового литерала один + строковый литерал два + байт для нулевого символа завершения и скопировать соответствующие литералы в этот буфер, а также убедиться, что он заканчивается нулем. . Или вы можете использовать библиотечные функции, например strcat
.
Без расширения 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 для более подробной информации.
#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);
}
Объединение любых двух строк в C может быть выполнено как минимум тремя способами: -
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;
}
В C у вас действительно нет строк в качестве универсального объекта первого класса. Вы должны управлять ими как массивами символов, а это значит, что вы должны определить, как вы хотите управлять своими массивами. Один из способов - это обычные переменные, например, помещенные в стек. Другой способ - разместить их динамически с помощью malloc
.
После сортировки вы можете скопировать содержимое одного массива в другой, чтобы объединить две строки с помощью strcpy
или strcat
.
Сказав это, C действительно имеет понятие «строковых литералов», которые представляют собой строки, известные во время компиляции. При использовании они будут массивом символов, помещенным в постоянную память. Однако можно объединить два строковых литерала, записав их рядом друг с другом, например, в результате "foo" "bar"
чего будет создан строковый литерал «foobar».
используя 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);
return memcpy(result, s1, len1);
. Несмотря на микрооптимизацию или, по крайней мере, небольшую корректировку кода, такие потенциальные улучшения основных строковых операций могут иметь значение, учитывая их широкое использование.