ฉันจะเพิ่มสองสายได้อย่างไร
ฉันพยายามname = "derp" + "herp";
แต่ฉันพบข้อผิดพลาด:
การแสดงออกจะต้องมีประเภทหนึ่งหรือ enum
ฉันจะเพิ่มสองสายได้อย่างไร
ฉันพยายามname = "derp" + "herp";
แต่ฉันพบข้อผิดพลาด:
การแสดงออกจะต้องมีประเภทหนึ่งหรือ enum
คำตอบ:
C ไม่มีการรองรับสตริงที่บางภาษาอื่นมี สตริงใน C เป็นเพียงตัวชี้ไปยังอาร์เรย์ของchar
ที่จะถูกยกเลิกโดยตัวละคร null แรก ไม่มีตัวดำเนินการเรียงต่อสตริงใน 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
หากคุณเกิดความรำคาญจากการทำงานคุณควรหลีกเลี่ยงการสแกนบัฟเฟอร์อินพุตซ้ำ ๆ เพื่อค้นหา null-terminator
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 <stdio.h>
int main(){
char name[] = "derp" "herp";
printf("\"%s\"\n", name);//"derpherp"
return 0;
}
David Heffernan อธิบายปัญหาในคำตอบของเขาและฉันเขียนรหัสที่ปรับปรุงแล้ว ดูด้านล่าง
เราสามารถเขียนฟังก์ชัน variadic ที่มีประโยชน์เพื่อเชื่อมสตริงจำนวนเท่าใดก็ได้:
#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
หมายถึงตัวชี้ null
ฉันจะสมมติว่าคุณต้องการมันสำหรับสิ่งเดียว ฉันจะถือว่าคุณเป็นนักพัฒนาพีซี
ใช้กองซ้อนลุค ใช้งานได้ทุกที่ อย่าใช้ malloc / ฟรีสำหรับการจัดสรรขนาดเล็กที่เคย
#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 KB ต่อสายอักขระไม่เพียงพอให้เพิ่มขนาดให้เป็นศูนย์และไม่ต้องกังวล - พวกมันจะปล่อยหน่วยความจำสแต็กที่ส่วนท้ายของขอบเขต
snprintf(result, sizeof result, "%s %s %s", s1, s2, s3);
คุณควรใช้หรือดีกว่าstrcat
strncat
Google it (คำหลักคือ "การต่อข้อมูล")
strncat()
เป็นฟังก์ชั่นที่กินเลือดออกยากที่จะใช้อย่างถูกต้อง อย่างรวดเร็วโดยไม่ต้องดูคู่มือคุณระบุความยาวstrncat()
เท่าใด ถ้าคุณพูดว่า "ความยาวของบัฟเฟอร์" คุณแค่แสดงให้เห็นถึงจุดของฉันเป็นอย่างดี มันมีส่วนต่อประสานที่ใช้งานง่ายและเมื่อคุณมีข้อมูลเพียงพอที่จะใช้อย่างปลอดภัยคุณไม่จำเป็นต้องใช้ฟังก์ชั่นในตอนแรก - มีตัวเลือกอื่น ๆ ที่เร็วกว่าและมีประสิทธิภาพมากกว่า (เช่นstrcpy()
หรือmemmove()
) ที่สามารถใช้งานได้ แทน. สวยมากไม่ว่าคำถามของ 'ฉันควรใช้อะไร' strncat()
ไม่ใช่คำตอบ
คุณไม่สามารถเพิ่มตัวอักษรสตริงเช่นเดียวกับใน C คุณต้องสร้างบัฟเฟอร์ขนาดของสตริงตัวอักษรหนึ่ง + สตริงตัวอักษรสอง + a ไบต์สำหรับอักขระการเลิกจ้างโมฆะและคัดลอกตัวอักษรที่สอดคล้องกับบัฟเฟอร์นั้นและตรวจสอบให้แน่ใจว่ามันถูกยกเลิกเป็นโมฆะ . strcat
หรือคุณสามารถใช้ฟังก์ชั่นเช่นห้องสมุด
ไม่มี GNU extension:
#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;
}
#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 สามารถทำได้อย่างน้อย 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;
}
ใน 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);
รหัสสามารถทำสำเนาของส่วนแรกของสตริงที่ผ่านมาแล้ว แม้ว่าการเพิ่มประสิทธิภาพแบบไมโครหรืออย่างน้อยบิตของการเล่นกอล์ฟรหัสการปรับปรุงที่เป็นไปได้ดังกล่าวในการดำเนินงานของสตริงพื้นฐานสามารถมีค่าให้ใช้งานได้สูง