Yanıtlar:
C, diğer bazı dillerin sahip olduğu dizeler için desteğe sahip değildir. C'deki bir dize char
, ilk null karakterle sonlandırılan bir diziye yalnızca bir göstericidir . C'de dize birleştirme operatörü yok.
strcat
İki dizeyi birleştirmek için kullanın . Bunu yapmak için aşağıdaki işlevi kullanabilirsiniz:
#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;
}
Bunu yapmanın en hızlı yolu bu değil, ama şimdi bunun için endişelenmemelisin. İşlevin, arayana bir yığın bellek ayrılmış bloğu döndürdüğünü ve bu belleğin sahipliğini aktardığını unutmayın. free
Artık ihtiyaç duyulmadığında , arayan kişinin hafızaya sorumluluğu vardır .
İşlevi şu şekilde çağırın:
char* s = concat("derp", "herp");
// do things with s
free(s); // deallocate the string
Performanstan rahatsız olsaydınız, boş sonlandırıcıyı arayan giriş arabelleklerini tekrar tekrar taramaktan kaçınmak istersiniz.
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;
}
Dizelerle çok fazla iş yapmayı planlıyorsanız, dizeler için birinci sınıf desteğe sahip farklı bir dil kullanmaktan daha iyi olabilirsiniz.
stpcpy
İlk dizenin sonuna bir işaretçi döndüren ilk sürümün küçük performans artışı :strcpy(stpcpy(result, s1), s2);
David Heffernan konuyu cevabında açıkladı ve ben geliştirilmiş kodu yazdım. Aşağıya bakınız.
İstediğiniz sayıda dizeyi birleştirmek için yararlı bir varyasyon işlevi yazabiliriz :
#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;
}
Çıktı:
// Empty line
a
ab
abc
Bellek sızıntılarını önlemek için ayrılan belleği gereksiz hale geldiğinde boşaltmanız gerektiğini unutmayın:
char *str = concat(2,"a","b");
println(str);
free(str);
int len
-> düşünün . Ayrıca -> boş gösterici anlamına gelir. size_t len
size_t
// room for NULL
// room for null character
NULL
Bir kereye mahsus şeyler için ihtiyacınız olduğunu varsayacağım. Bir PC geliştiricisi olduğunuzu varsayacağım.
Yığını kullan, Luke. Her yerde kullanın. , Malloc / küçük tahsisleri için ücretsiz kullanmayın hiç .
#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);
}
}
Dize başına 10 KB yeterli olmazsa, boyuta sıfır ekleyin ve rahatsız etmeyin - yine de kapsamların sonunda yığın belleklerini serbest bırakırlar.
snprintf(result, sizeof result, "%s %s %s", s1, s2, s3);
Kullanmalısın strcat
ya da daha iyisi strncat
. Google it (anahtar kelime "birleştiriliyor").
strncat()
doğru kullanmak son derece zor bir işlevdir. Hızla, kılavuza bakmadan, hangi uzunlukta belirtmeyi seçersiniz strncat()
? Eğer "tamponun uzunluğu" derseniz, benim açımdan gayet güzel bir örnek verdiniz. Karşı sezgisel bir arayüze sahiptir ve güvenli bir şekilde kullanmak için yeterli veriye sahipseniz, işlevi ilk etapta kullanmanız gerekmez - kullanılabilecek başka, daha hızlı ve daha verimli alternatifler ( strcpy()
veya gibi memmove()
) vardır. yerine. Hemen hemen 'ne kullanmalıyım' sorusu ne olursa olsun strncat()
, cevap değil.
C'de olduğu gibi dize değişmezleri ekleyemezsiniz . Boş sonlandırma karakteri için dize değişmez bir + dize değişmez iki + bir bayt boyutunda bir arabellek oluşturmalı ve karşılık gelen değişmezleri bu ara belleğe kopyalamanız ve ayrıca boş bırakıldığından emin olmanız gerekir. . Veya gibi kütüphane işlevlerini kullanabilirsiniz strcat
.
GNU uzantısı olmadan:
#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;
}
Alternatif olarak GNU uzantısı ile:
#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;
}
Daha fazla bilgi için malloc , free ve asprintf'e bakınız.
#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'de herhangi iki dizeyi birleştirmek en az 3 yolla yapılabilir: -
1) Dize 2'yi Dize 1'in sonuna kopyalayarak
#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) Dize 1 ve dize 2'yi dize 3'e kopyalayarak
#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 () fonksiyonunu kullanarak
#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'de, genel bir birinci sınıf nesne olarak dizeleriniz gerçekten yoktur. Bunları karakter dizileri olarak yönetmelisiniz, yani dizilerinizi nasıl yönetmek istediğinizi belirlemeniz gerekir. Bunun bir yolu normal değişkenlerdir, örneğin yığına yerleştirilir. Başka bir yol, bunları kullanarak dinamik olarak ayırmaktırmalloc
.
Bunu sıraladıktan sonra, strcpy
veya kullanarak iki dizeyi birleştirmek için bir dizinin içeriğini diğerine kopyalayabilirsiniz.strcat
.
Bunu söyledikten sonra, C derleme zamanında bilinen dizeler olan "dizi değişmezleri" kavramına sahiptir. Kullanıldığında, salt okunur belleğe yerleştirilmiş bir karakter dizisi olacaktır. Bununla birlikte, iki dize değişmezini "foo" "bar"
, "foobar" dize değerini oluşturacak şekilde, olduğu gibi yan yana yazarak birleştirmek mümkündür .
memcpy kullanma
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);
. Her ne kadar bir mikro optimizasyon veya en azından biraz kod golf olsa da, temel dizi işlemlerindeki bu tür potansiyel iyileştirmeler yüksek kullanımları göz önüne alındığında değere sahip olabilir.