Як об'єднати два рядки в 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: це лінійно.
Наваз

30

Оскільки це C ++, чому б не використовувати std::stringзамість char*? Конкатенація буде тривіальною:

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

1
Варто зауважити, що тривіальне використання має нетривіальний цінник щодо продуктивності виконання. Найгірший випадок - це те, що operator+=виконує як розподіл, так і розподіл. Купи розподілу є одними з найдорожчих операцій, які ми зазвичай робимо.
IIнеочікуваний

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 + = вимагає можливого перерозподілу.
Ешлі Дункан

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 string, життя було б набагато простіше.

якщо у вас є старий рядок стилю, ви можете перейти до класу string

    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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.