Какой самый простой способ конвертировать int
в эквивалент string
в C ++. Я знаю о двух методах. Есть ли более простой способ?
(1)
int a = 10;
char *intStr = itoa(a);
string str = string(intStr);
(2)
int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
c++
string
int
type-conversion
Nemo
источник
источник
itoa()
принимает три параметра.Ответы:
C ++ 11 вводит
std::stoi
(и варианты для каждого числового типа) иstd::to_string
, аналоги Catoi
и,itoa
но выражается черезstd::string
.поэтому я думаю о кратчайшем пути. Вы даже можете опустить наименование типа, используя
auto
ключевое слово:Примечание: см. [String.conversions] ( 21,5 в n3242 )
источник
to_string
не участникstd
исправления: stackoverflow.com/questions/12975341/…g++ -std=c++11 someFile.cc
std
в каждый известный мне компилятор, кроме одного.Error : No instance of overloaded function "std::to_string" matches the argument list
я использую VS2010 c ++string s = to_string((_ULonglong)i);
Пару лет спустя, начав дискуссию с @ v.oddou, C ++ 17 наконец-то предоставил способ сделать изначально основанное на макросах решение, не зависящее от типа (сохранено ниже), не проходя через безобразие макросов.
Применение:
Оригинальный ответ:
Поскольку «преобразование ... в строку» является повторяющейся проблемой, я всегда определяю макрос SSTR () в центральном заголовке моих источников C ++:
Использование настолько просто, насколько это возможно:
Вышесказанное совместимо с C ++ 98 (если вы не можете использовать C ++ 11
std::to_string
) и не требует никаких сторонних включений (если вы не можете использовать Boostlexical_cast<>
); оба эти решения имеют лучшую производительность.источник
dynamic_cast
но я использую Clang для компиляции, поэтому он жалуется на это. Если я просто опущу,dynamic_cast
то это прекрасно скомпилируется; какой целиdynamic_cast
служит в этом случае? Мы уже создаемostringstream
, так зачем его кастовать?ostringstream
, мы позвонилиoperator<<()
на него, который возвращаетсяostream &
- для которых.str()
не определен. Мне действительно интересно, как clang сделал бы эту работу без приведения (или почему он генерирует ошибку с ним). Эта конструкция публикуется во многих местах, и я уже более десяти лет использую ее на разных компиляторах, в том числе MSVC, GCC и XLC, поэтому я довольно удивлен, что ее не устраивает.do { } while( 0 )
ничего бы не добавил. С 2. и 3. Вы, вероятно, получили точку зрения - это можно сделать с помощью статического приведения, и, возможно, один из ваших мастеров шаблонов мог бы придумать «более приятный» интерфейс. Но, как я уже сказал, это ни в коем случае не выдумка меня самого. Посмотрите вокруг, этот макрос (макрос!) Довольно вездесущ. Это случай ПОЛА сам по себе. Я мог бы немного поиграть с этим, чтобы сделать его более «обтекаемым».Я обычно использую следующий метод:
Это подробно описано здесь .
источник
ss
вам нужноss.clear()
это. Я видел неожиданные результаты без этой инициализации.clear()
вновь созданныйostringstream
объект.clear()
сбрасывает флаги error / eof, и еще не было сгенерировано ни одного условия error / eof.NumberToString(23213.123)
производит,23213.1
аstd::to_string(23213.123)
производит.23213.123000
Что там происходит?Вероятно, наиболее распространенный простой способ - это, по сути, ваш второй выбор в шаблон с именем
lexical_cast
, например, в Boost , поэтому ваш код выглядит следующим образом:Одним из достоинств этого является то, что он поддерживает и другие приведения (например, в противоположном направлении работает так же хорошо).
Также обратите внимание, что хотя Boost lexical_cast изначально начинался с простой записи в поток строк, а затем извлекался из потока, теперь у него есть пара дополнений. Прежде всего, были добавлены специализации для нескольких типов, поэтому для многих распространенных типов это существенно быстрее, чем использование stringstream. Во-вторых, теперь он проверяет результат, поэтому (например), если вы преобразуете строку в переменную
int
, она может выдать исключение, если строка содержит что-то, что не может быть преобразовано вint
(например,1234
успешно выполнится , но123abc
сгенерирует) ,Начиная с C ++ 11, есть
std::to_string
функция, перегруженная для целочисленных типов, поэтому вы можете использовать такой код:Стандарт определяет их как эквивалентное выполнению преобразования
sprintf
(с использованием спецификатора преобразования, который соответствует предоставленному типу объекта, например,%d
forint
), в буфер достаточного размера, а затем созданиеstd::string
содержимого этого буфера.источник
Если у вас установлен Boost (что вам и нужно):
источник
Было бы проще использовать stringstreams:
Или сделайте функцию:
источник
Не то, что я знаю, в чистом C ++. Но небольшая модификация того, что вы упомянули
должно работать, и это довольно коротко.
источник
itoa()
не является стандартной функцией!Вы можете использовать
std::to_string
доступные в C ++ 11, как предложено Matthieu M .:Или, если производительность имеет решающее значение (например, если вы делаете много переходов), вы можете использовать
fmt::format_int
с {} FMT библиотеки преобразовать целое числоstd::string
:Или строка C:
Последний не выполняет динамического выделения памяти и более чем в 10 раз быстрее, чем
std::to_string
в тестах Boost Karma. См. Быстрое преобразование целых чисел в строки в C ++ для получения дополнительной информации.Обратите внимание, что оба потока потокобезопасны.
В отличие от
std::to_string
,fmt::format_int
не требует C ++ 11 и работает с любым компилятором C ++.Отказ от ответственности: я являюсь автором библиотеки {fmt}.
источник
c_str()
возвращает указатель на буфер, объявленный внутриfmt::FormatInt
класса - поэтому возвращенный указатель будет недействительным при точка с запятой - см. также stackoverflow.com/ru/questions/4214153/lifetime-of-temporariesstd::string::c_str()
(таким образом, именование). Если вы хотите использовать его вне полного выражения, создайте объект.FormatInt f(42);
Тогда вы можете использовать егоf.c_str()
без опасности его уничтожения.sprintf()
довольно хорошо для преобразования формата. Затем вы можете назначить полученную строку C строке C ++, как вы это делали в 1.источник
NULL
нулевым размером, чтобы получить необходимый размер буфера.snprintf
(обратите внимание на префикс SNP ) иsprintf
(обратите внимание на префикс SP ). Вы передаете размер первому, и он заботится о том, чтобы не переполниться, однако последний не знает размер буфера и, таким образом, может переполниться.snprintf
сначала назвать вариант, а затемsprintf
вариант. Поскольку размер буфера уже известен, вызовsprintf
становится полностью безопасным.Сначала включите:
Второй добавить метод:
Используйте метод как это:
или
источник
Использование stringstream для преобразования чисел опасно!
См. Http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/, где рассказывается, что
operator<<
вставляет форматированный вывод.В зависимости от текущей локали целое число, превышающее 3 цифры, может быть преобразовано в строку из 4 цифр с добавлением дополнительного разделителя тысяч.
Например,
int = 1000
может быть преобразован в строку1.001
. Это может привести к тому, что операции сравнения вообще не будут работать.Поэтому я настоятельно рекомендую использовать
std::to_string
способ. Это проще и делает то, что вы ожидаете.Обновлено (см. Комментарии ниже) :
источник
std::to_string
используется текущая локаль (см. En.cppreference.com/w/cpp/string/basic_string/to_string , раздел «Примечания»). Почти все стандартные инструменты (от строковых потоков доsprintf
, но также иsscanf
т. Д.) Используют текущую локаль. Я не знал об этом до недавнего времени, когда это сильно ударило меня. В настоящее время используют домашние вещи, не трудно сделать.Для C ++ 98 есть несколько вариантов:
boost/lexical_cast
Boost не является частью библиотеки C ++, но содержит много полезных расширений библиотеки.
Что касается времени выполнения,
lexical_cast
операция занимает около 80 микросекунд (на моей машине) при первом преобразовании, а затем значительно ускоряется, если выполняется избыточно.itoa
Это означает, что
gcc
/g++
не может скомпилировать код, используяitoa
.Нет времени выполнения, чтобы сообщить. У меня не установлена Visual Studio, которая, как сообщается, может компилироваться
itoa
.sprintf
sprintf
является стандартной библиотечной функцией C, которая работает со строками C и является вполне допустимой альтернативой.stdio.h
Заголовок не может быть необходимым. Что касается времени выполнения,sprintf
операция занимает около 40 микросекунд (на моей машине) при первом преобразовании, а затем значительно ускоряется, если выполняется избыточно.stringstream
Это основной способ преобразования целых чисел в строки библиотеки C ++ и наоборот. Существуют аналогичные родственные функции,
stringstream
которые дополнительно ограничивают предполагаемое использование потока, напримерostringstream
. Использование, вostringstream
частности, говорит читателю вашего кода, что вы<<
, по сути, собираетесь использовать только оператор. Эта функция - все, что особенно необходимо для преобразования целого числа в строку. Смотрите этот вопрос для более детального обсуждения.Что касается времени выполнения,
ostringstream
операция занимает около 71 микросекунды (на моей машине), а затем значительно ускоряется, если выполняется избыточно, но не настолько, как предыдущие функции .Конечно, есть и другие варианты, и вы можете даже включить один из них в свои собственные функции, но это предлагает аналитический взгляд на некоторые из популярных.
источник
C ++ 17 предоставляет std :: to_chars в качестве высокопроизводительной независимой от локали альтернативы.
источник
Довольно просто добавить синтаксический сахар, который позволяет составлять строки на лету, как поток
Теперь вы можете добавлять все, что хотите (при условии, что
<< (std::ostream& ..)
для него определен оператор ),strmake()
и использовать его вместоstd::string
.Пример:
источник
Редактируется. Если вам нужно быстрое преобразование целого числа с фиксированным числом цифр в символ *, дополненное слева до '0' , это пример для архитектуры с прямым порядком байтов (все x86, x86_64 и другие):
Если вы конвертируете двузначное число:
Если вы конвертируете трехзначное число:
Если вы конвертируете четырехзначное число:
И так далее до семизначных чисел. В этом примере
n
задано целое число. После преобразования его строковое представление может быть доступно как(char*)&s
:ПРИМЕЧАНИЕ. Если вам нужен порядок байтов с прямым порядком байтов, хотя я не проверял его, но вот пример: для трехзначного числа это
int32_t s = 0x00303030 | (n/100)<< 24 | (n/10%10)<<16 | (n%10)<<8;
для четырехзначных чисел (64-разрядная арка):int64_t s = 0x0000000030303030 | (n/1000)<<56 | (n/100%10)<<48 | (n/10%10)<<40 | (n%10)<<32;
я думаю, что это должно работать.источник
Использование:
источник
Я использую:
Это работает на моих Windows и Linux G ++ компиляторах.
источник
sprintf
хорошо известен для вставки любых данных в строку требуемого формата.Вы можете преобразовать
char *
массив в строку, как показано в третьей строке.источник
Это сработало для меня -
Мой код:
источник
stringstream
?std::to_string()
using namespace std;
:)C ++ 11 введен
std::to_string()
для числовых типов:источник
Использование:
источник
источник
Если вы используете MFC , вы можете использовать
CString
:источник
источник
Теперь вы можете использовать
to_string(5)
.источник
std
пространство имен - это тоже не то, что вы должны делать. Кроме того, это не похоже_MAX_INT_DIG
на стандартный макрос, поэтому, если он определен неправильно, этот код обладает большим потенциалом вызывать неопределенное поведение. -1Я думаю, что использовать
stringstream
довольно просто:источник
Вы используете тип счетчика алгоритма для преобразования в строку. Я получил эту технику от программирования компьютеров Commodore 64 . Это также хорошо для программирования игр.
Вы берете целое число и берете каждую цифру, которая взвешена на степени 10. Поэтому предположим, что целое число равно 950.
Если целое число равно или больше 100 000, то вычтите 100 000 и увеличьте счетчик в строке на ["000000"];
продолжайте делать это до тех пор, пока в позиции 100 000 больше не останется цифр. Отбросьте еще одну степень десяти.
Если целое число равно или больше 10000, то вычтите 10000 и увеличьте счетчик в строке на ["000000"] + 1 позиция;
продолжайте делать это до тех пор, пока не останется цифр в позиции 10000.
Отбросьте еще одну степень десяти
Я знаю, что 950 слишком мал для использования в качестве примера, но я надеюсь, что вы поняли идею.
источник