Как объединить несколько строк C ++ в одну строку? - PullRequest
131 голосов
/ 19 марта 2009

C # имеет синтаксическую функцию, в которой вы можете объединить множество типов данных в одну строку.

string s = new String();
s += "Hello world, " + myInt + niceToSeeYouString;
s += someChar1 + interestingDecimal + someChar2;

Что будет эквивалентом в C ++? Насколько я вижу, вам придется делать все это на отдельных строках, поскольку он не поддерживает несколько строк / переменных с оператором +. Это нормально, но выглядит не очень аккуратно.

string s;
s += "Hello world, " + "nice to see you, " + "or not.";

Приведенный выше код выдает ошибку.

Ответы [ 24 ]

216 голосов
/ 19 марта 2009
#include <sstream>
#include <string>

std::stringstream ss;
ss << "Hello, world, " << myInt << niceToSeeYouString;
std::string s = ss.str();

Взгляните на статью Гуру Недели от Херба Саттера: Строковый форматер усадебной фермы

58 голосов
/ 14 ноября 2014

За 5 лет никто не упомянул .append?

#include <string>

std::string s;
s.append("Hello world, ");
s.append("nice to see you, ");
s.append("or not.");
58 голосов
/ 19 марта 2009
s += "Hello world, " + "nice to see you, " + "or not.";

Эти литералы массива символов не являются C ++ std :: strings - вам нужно их преобразовать:

s += string("Hello world, ") + string("nice to see you, ") + string("or not.");

Для преобразования целых чисел (или любого другого типа стрима) вы можете использовать повышение lexical_cast или предоставить свою собственную функцию:

template <typename T>
string Str( const T & t ) {
   ostringstream os;
   os << t;
   return os.str();
}

Теперь вы можете говорить такие вещи, как:

string s = "The meaning is " + Str( 42 );
40 голосов
/ 19 марта 2009

Ваш код может быть записан как 1 ,

s = "Hello world," "nice to see you," "or not."

... но я сомневаюсь, что это то, что вы ищете. В вашем случае вы, вероятно, ищете потоки:

std::stringstream ss;
ss << "Hello world, " << 42 << "nice to see you.";
std::string s = ss.str();

1" можно записать как ": это работает только для строковых литералов. Конкатенация выполняется компилятором.

22 голосов
/ 02 июля 2014

Используя пользовательские литералы C ++ 14 и std::to_string, код становится проще.

using namespace std::literals::string_literals;
std::string str;
str += "Hello World, "s + "nice to see you, "s + "or not"s;
str += "Hello World, "s + std::to_string(my_int) + other_string;

Обратите внимание, что объединение строковых литералов может быть выполнено во время компиляции. Просто удалите +.

str += "Hello World, " "nice to see you, " "or not";
16 голосов
/ 28 мая 2014

Чтобы предложить решение, которое является более однострочным: можно реализовать функцию concat, чтобы уменьшить «классическое» решение на основе строкового потока до одного оператора . Он основан на вариационных шаблонах и идеальной пересылке.


Использование:

std::string s = concat(someObject, " Hello, ", 42, " I concatenate", anyStreamableType);

Реализация:

void addToStream(std::ostringstream&)
{
}

template<typename T, typename... Args>
void addToStream(std::ostringstream& a_stream, T&& a_value, Args&&... a_args)
{
    a_stream << std::forward<T>(a_value);
    addToStream(a_stream, std::forward<Args>(a_args)...);
}

template<typename... Args>
std::string concat(Args&&... a_args)
{
    std::ostringstream s;
    addToStream(s, std::forward<Args>(a_args)...);
    return s.str();
}
7 голосов
/ 19 марта 2009

boost :: format

или std :: stringstream

std::stringstream msg;
msg << "Hello world, " << myInt  << niceToSeeYouString;
msg.str(); // returns std::string object
6 голосов
/ 19 сентября 2017

Фактическая проблема состояла в том, что конкатенация строковых литералов с + не удалась в C ++:

string s;
s += "Hello world, " + "nice to see you, " + "or not.";
Приведенный выше код выдает ошибку.

В C ++ (также в C) вы объединяете строковые литералы, просто помещая их рядом друг с другом:

string s0 = "Hello world, " "nice to see you, " "or not.";
string s1 = "Hello world, " /*same*/ "nice to see you, " /*result*/ "or not.";
string s2 = 
    "Hello world, " /*line breaks in source code as well as*/ 
    "nice to see you, " /*comments don't matter*/ 
    "or not.";

Это имеет смысл, если вы генерируете код в макросах:

#define TRACE(arg) cout << #arg ":" << (arg) << endl;

... простой макрос, который можно использовать вот так

int a = 5;
TRACE(a)
a += 7;
TRACE(a)
TRACE(a+7)
TRACE(17*11)

( live демо ... )

или, если вы настаиваете на использовании + для строковых литералов (как уже предложено underscore_d ):

string s = string("Hello world, ")+"nice to see you, "+"or not.";

Другое решение объединяет строку и const char* для каждого этапа объединения

string s;
s += "Hello world, "
s += "nice to see you, "
s += "or not.";
4 голосов
/ 07 октября 2017
auto s = string("one").append("two").append("three")
4 голосов
/ 29 апреля 2018

С библиотекой {fmt} вы можете сделать:

auto s = fmt::format("{}{}{}", "Hello world, ", myInt, niceToSeeYouString);

Подмножество библиотеки предлагается для стандартизации как P0645 Форматирование текста , и, если оно будет принято, приведенное выше станет:

auto s = std::format("{}{}{}", "Hello world, ", myInt, niceToSeeYouString);

Отказ от ответственности : я являюсь автором библиотеки {fmt}.

...