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.";
Приведенный выше код выдает ошибку.
c++
string
compiler-errors
concatenation
Ник Болтон
источник
источник
char *
указатели друг на друга. Вот что порождает ошибку - потому что суммирование указателей бессмысленно. Как отмечено ниже, превратите хотя бы 1-й операнд в astd::string
, и ошибки нет вообще.Ответы:
Взгляните на эту статью Гуру Недели от Херба Саттера: Строковые форматеры усадебной фермы
источник
std::string s = static_cast<std::ostringstream&>(std::ostringstream().seekp(0) << "HelloWorld" << myInt << niceToSeeYouString).str();
std::stringstream ss; ss << "Hello, world, " << myInt << niceToSeeYouString; std::string s = ss.str();
в значительной степени однострочныйЧерез 5 лет никто не упомянул
.append
?источник
s.append("One"); s.append(" line");
s.append("One").append(" expression");
Может, мне следует отредактировать оригинал, чтобы использовать возвращаемое значение таким образом?s
в другой строке в эквивалентном коде C # и в своем некомпилируемом коде C ++. Его желаемый язык C ++,s += "Hello world, " + "nice to see you, " + "or not.";
который можно написатьs.append("Hello world, ").append("nice to see you, ").append("or not.");
append
является то, что он также работает, когда строки содержат символы NUL.Эти литералы символьного массива не являются C ++ std :: strings - их нужно преобразовать:
Чтобы конвертировать целые числа (или любой другой тип стрима), вы можете использовать повышение lexical_cast или предоставить свою собственную функцию:
Теперь вы можете сказать такие вещи, как:
источник
string("Hello world")
, выполняются черезoperator+()
определенные в классеstring
. Еслиstring
в выражении нет объекта, конкатенация становится простой суммой указателей на символыchar*
.Ваш код может быть записан как 1 ,
... но я сомневаюсь, что это то, что вы ищете. В вашем случае вы, вероятно, ищете потоки:
1 « можно записать как »: это работает только для строковых литералов. Конкатенация выполняется компилятором.
источник
const char smthg[] = "smthg"
: / Это ошибка?#define
обойти это, хотя это приносит свои проблемы.Используя пользовательские литералы C ++ 14,
std::to_string
код становится проще.Обратите внимание, что объединение строковых литералов может быть выполнено во время компиляции. Просто удалите
+
.источник
std::literals::string_literals
, а не концепцию UDL.Чтобы предложить решение, которое является более однострочным:
concat
можно реализовать функцию , которая сводит «классическое» решение на основе строкового потока к одному выражению . Он основан на вариационных шаблонах и идеальной пересылке.Использование:
Реализация:
источник
В C ++ 20 вы сможете делать:
До этого вы могли бы сделать то же самое с библиотекой {fmt} :
Отказ от ответственности : я автор {fmt}.
источник
повышение :: формат
или std :: stringstream
источник
Актуальная проблема в том , что конкатенации строковых литералов
+
терпит неудачу в C ++:В C ++ (также в C) вы объединяете строковые литералы, просто помещая их рядом друг с другом:
Это имеет смысл, если вы генерируете код в макросах:
... простой макрос, который можно использовать следующим образом
( живая демонстрация ... )
или, если вы настаиваете на использовании
+
строковых литералов for (как уже предложено underscore_d ):Другое решение объединяет строку и a
const char*
для каждого этапа объединенияисточник
sprintf
- это вариант, но есть также std :: stringstream, который предотвращает проблемы с буферами меньшего размера .источник
Вам нужно было бы определить operator + () для каждого типа данных, который вы хотите связать со строкой, однако, поскольку operator << определен для большинства типов, вы должны использовать std :: stringstream.
Блин, бей на 50 секунд ...
источник
std::string operator+(std::string s, int i){ return s+std::to_string(i); }
Если вы напишите
+=
, это выглядит почти так же, как C #источник
Как говорили другие, основная проблема с кодом OP заключается в том, что оператор
+
не объединяетconst char *
; это работаетstd::string
, хотя.Вот еще одно решение, которое использует лямбда-символы C ++ 11
for_each
и позволяет предоставлятьseparator
для разделения строк:Использование:
Кажется, он хорошо масштабируется (линейно), по крайней мере, после быстрого теста на моем компьютере; вот быстрый тест, который я написал:
Результаты (миллисекунды):
источник
Может быть, вам нравится мое решение "Streamer", чтобы сделать это в одну строку:
источник
Вот однострочное решение:
Хотя это немного уродливо, я думаю, что это примерно так же чисто, как вы, кошка, получаете в C ++.
Мы приводим первый аргумент к a
std::string
и затем используем (слева направо) порядок вычисления,operator+
чтобы убедиться, что его левый операнд всегда равен astd::string
. Таким образом, мы объединяемstd::string
слева сconst char *
операндом справа и возвращаем еще одинstd::string
, каскадный эффект.Примечание: Есть несколько вариантов для правого операнда, в том числе
const char *
,std::string
иchar
.Вам решать, будет ли магическое число 13 или 6227020800.
источник
Вы можете использовать этот заголовок для этого: https://github.com/theypsilon/concat
Под капотом вы будете использовать std :: ostringstream.
источник
Если вы хотите использовать его,
c++11
вы можете использовать определяемые пользователем строковые литералы и определить два шаблона функций, которые перегружают оператор «плюс» дляstd::string
объекта и любого другого объекта. Единственный подводный камень - не перегружать операторы plusstd::string
, иначе компилятор не знает, какой оператор использовать. Вы можете сделать это с помощью шаблонаstd::enable_if
изtype_traits
. После этого строки ведут себя так же, как в Java или C #. Смотрите мой пример реализации для деталей.Основной код
Файл c_sharp_strings.hpp
Включите этот заголовочный файл во все места, где вы хотите иметь эти строки.
источник
Как-то так у меня работает
источник
На основе вышеупомянутых решений я создал класс var_string для своего проекта, чтобы облегчить жизнь. Примеры:
Сам класс:
Все еще задаетесь вопросом, будет ли что-то лучше в C ++?
источник
В с11:
это позволит вам создать вызов функции следующим образом:
напечатает: номер сообщения: 10
источник
Вы также можете «расширить» класс строки и выбрать оператор, который вы предпочитаете (<<, &, | и т. д.)
Вот код, использующий оператор <<, чтобы показать, что нет конфликта с потоками
примечание: если вы раскомментируете s1.reserve (30), есть только 3 запроса оператора new () (1 для s1, 1 для s2, 1 для резерва; к сожалению, вы не можете зарезервировать во время конструктора); без резерва, s1 должен запрашивать больше памяти по мере роста, так что это зависит от фактора роста реализации вашего компилятора (в нашем примере это, кажется, 1,5, 5 вызовов new ())
источник
Stringstream с простым макросом препроцессора с использованием лямбда-функции выглядит неплохо:
а потом
источник
Это работает для меня:
Вывод:
источник
const
или (если требуется нулевое хранилище), чемenum
было бы?Вы пытались избежать + =? вместо этого используйте var = var + ... у меня это сработало.
источник
#include <iostream.h> // string
#include <system.hpp> // ansiString