วิธีการเชื่อมสองสตริงใน C ++?


100

ฉันมีตัวแปรคลาสส่วนตัวchar name[10]ที่ฉันต้องการเพิ่ม.txtส่วนขยายเพื่อให้ฉันสามารถเปิดไฟล์ที่มีอยู่ในไดเร็กทอรี

ฉันจะไปเกี่ยวกับเรื่องนี้ได้อย่างไร?

ควรสร้างตัวแปรสตริงใหม่ที่เก็บสตริงที่ต่อกัน

คำตอบ:


160

ก่อนอื่นอย่าใช้char*หรือchar[N]. ใช้std::stringแล้วทุกอย่างจะกลายเป็นเรื่องง่าย!

ตัวอย่าง,

std::string s = "Hello";
std::string greet = s + " World"; //concatenation easy!

ง่ายใช่มั้ย?

ตอนนี้หากคุณต้องการchar const *เหตุผลบางอย่างเช่นเมื่อคุณต้องการส่งผ่านไปยังฟังก์ชันบางอย่างคุณสามารถทำได้:

some_c_api(s.c_str(), s.size()); 

สมมติว่าฟังก์ชันนี้ประกาศเป็น:

some_c_api(char const *input, size_t length);

สำรวจstd::stringตัวเองโดยเริ่มจากที่นี่:

หวังว่าจะช่วยได้


3
ความซับซ้อนของเวลาของการต่อสายอักขระนี้คืออะไร?
d34th4ck3r

@ d34th4ck3r: มันเป็นเส้นตรง
Nawaz

30

เนื่องจากเป็น C ++ ทำไมไม่ใช้std::stringแทนchar*? การเชื่อมต่อจะไม่สำคัญ:

std::string str = "abc";
str += "another";

1
ที่น่าสังเกตการใช้งานที่ไม่สำคัญมาพร้อมกับป้ายราคาที่ไม่สำคัญเกี่ยวกับประสิทธิภาพของรันไทม์ กรณีที่แย่ที่สุดคือoperator+=ดำเนินการทั้งการจัดสรรและการจัดสรร การจัดสรรฮีปเป็นหนึ่งในการดำเนินการที่แพงที่สุดที่เรามักทำ
สืบได้

15

หากคุณกำลังเขียนโปรแกรมในภาษา C สมมติว่าnameเป็นอาร์เรย์ที่มีความยาวคงที่จริง ๆ อย่างที่คุณพูดคุณต้องทำสิ่งต่อไปนี้:

char filename[sizeof(name) + 4];
strcpy (filename, name) ;
strcat (filename, ".txt") ;
FILE* fp = fopen (filename,...

คุณเห็นแล้วว่าทำไมทุกคนถึงแนะนำstd::string?


1
คุณไม่เห็นว่าผู้ชายถามคำถามใน c ++ และไม่ได้อยู่ใน C ??
IcyFlame

21
คุณไม่เห็นที่ฉันพูดว่า "ถ้าคุณกำลังเขียนโปรแกรม ... "?
TonyK

คุณไม่คิดว่าคำตอบนี้ไม่เกี่ยวข้องกับคำถามนี้หรือ?
IcyFlame

9
ฉันคิดว่าสิ่งนี้มีความเกี่ยวข้องเนื่องจาก "ผู้ชาย" ใช้ char แทน std :: string นอกจากนี้ยังแสดงวิธีการเชื่อมต่อที่ชัดเจนซึ่งไม่ได้แสดงในคำตอบที่ได้รับการโหวตมากที่สุด อย่างน้อยฉันก็ได้เรียนรู้อะไรบางอย่างกับมัน
gvegayon

1
นอกจากนี้ยังแสดงวิธีการเชื่อมต่อสตริงโดยไม่มีการจัดสรรหน่วยความจำแบบไดนามิก เว้นแต่ฉันจะผิด std :: string operator + = ต้องมีการจัดสรรใหม่ที่เป็นไปได้
Ashley Duncan

7

มีstrcat ()ฟังก์ชันจากไลบรารี C ที่พอร์ตซึ่งจะทำการเชื่อมต่อ "สตริงสไตล์ C" ให้คุณ

BTW แม้ว่า C ++ จะมีฟังก์ชั่นมากมายในการจัดการกับสตริงสไตล์ C แต่ก็อาจเป็นประโยชน์สำหรับคุณที่จะลองใช้ฟังก์ชันของคุณเองที่ทำเช่นนั้นเช่น:

char * con(const char * first, const char * second) {
    int l1 = 0, l2 = 0;
    const char * f = first, * l = second;

    // step 1 - find lengths (you can also use strlen)
    while (*f++) ++l1;
    while (*l++) ++l2;

    char *result = new char[l1 + l2];

    // then concatenate
    for (int i = 0; i < l1; i++) result[i] = first[i];
    for (int i = l1; i < l1 + l2; i++) result[i] = second[i - l1];

    // finally, "cap" result with terminating null char
    result[l1+l2] = '\0';
    return result;
}

... และแล้ว ...

char s1[] = "file_name";
char *c = con(s1, ".txt");

... file_name.txtผลจากการที่เป็น

คุณอาจถูกล่อลวงให้เขียนของคุณเองoperator +อย่างไรก็ตามตัวดำเนินการ IIRC เกินพิกัดโดยมีเพียงพอยน์เตอร์เนื่องจากอาร์กิวเมนต์ไม่ได้รับอนุญาต

นอกจากนี้อย่าลืมว่าผลลัพธ์ในกรณีนี้ถูกจัดสรรแบบไดนามิกดังนั้นคุณอาจต้องการเรียกลบเพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจำหรือคุณสามารถปรับเปลี่ยนฟังก์ชันเพื่อใช้อาร์เรย์อักขระที่จัดสรรแบบสแต็กได้หากมีความยาวเพียงพอ


ดูความคิดเห็นของฉันต่อคำตอบของ IcyFlame
TonyK

3
นอกจากนี้ยังมีstrncat()ฟังก์ชั่นที่มักจะเป็นทางเลือกที่ดีกว่า
nogard

@nogard: strncatไม่เกี่ยวข้องที่นี่เนื่องจากเราทราบความยาวของพารามิเตอร์ที่สอง".txt"แล้ว มันก็จะเป็นstrncat(name, ".txt", 4)เช่นนั้นซึ่งไม่ได้ประโยชน์อะไรเลย
TonyK


0

จะดีกว่าถ้าใช้คลาสสตริง C ++ แทนสตริง C แบบเก่าชีวิตจะง่ายขึ้นมาก

หากคุณมีสตริงแบบเก่าอยู่แล้วคุณสามารถแอบแฝงคลาสสตริงได้

    char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    cout<<greeting + "and there \n"; //will not compile because concat does \n not work on old C style string
    string trueString = string (greeting);
    cout << trueString + "and there \n"; // compiles fine
    cout << trueString + 'c'; // this will be fine too. if one of the operand if C++ string, this will work too

0

C ++ 14

std::string great = "Hello"s + " World"; // concatenation easy!

ตอบคำถาม:

auto fname = ""s + name + ".txt";

-2
//String appending
#include <iostream>
using namespace std;

void stringconcat(char *str1, char *str2){
    while (*str1 != '\0'){
        str1++;
    }

    while(*str2 != '\0'){
        *str1 = *str2;
        str1++;
        str2++;
    }
}

int main() {
    char str1[100];
    cin.getline(str1, 100);  
    char str2[100];
    cin.getline(str2, 100);

    stringconcat(str1, str2);

    cout<<str1;
    getchar();
    return 0;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.