Альтернатива itoa() для преобразования целого в строку С++?
Мне было интересно, есть ли альтернатива itoa()
для преобразования целого числа в строку, потому что когда я запускаю его в visual Studio, я получаю предупреждения, а когда пытаюсь создать свою программу под Linux, я получаю ошибку компиляции.
Ответы
Ответ 1
В С++ 11 вы можете использовать std::to_string
:
#include <string>
std::string s = std::to_string(5);
Если вы работаете с С++ 11, вы можете использовать потоки С++:
#include <sstream>
int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();
Взято из http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/
Ответ 2
boost:: lexical_cast работает очень хорошо.
#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
std::string foo = boost::lexical_cast<std::string>(argc);
}
Ответ 3
археология
itoa была нестандартной вспомогательной функцией, предназначенной для дополнения стандартной функции atoi и, вероятно, скрывающей sprintf (большинство ее функций могут быть реализованы с точки зрения sprintf): http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html
The C Way
Используйте sprintf. Или snprintf. Или любой инструмент, который вы найдете.
Несмотря на то, что некоторые функции не соответствуют стандарту, как справедливо упоминается "onebyone" в одном из его комментариев, большинство компиляторов предложит вам альтернативу (например, Visual С++ имеет свой собственный _snprintf, который вы можете ввести в snprintf, если вам нужно она).
Способ С++.
Используйте потоки С++ (в текущем случае std:: stringstream (или даже устаревший std:: strstream, предложенный Хербом Саттером в одной из его книг, потому что он несколько быстрее).
Заключение
Вы находитесь на С++, что означает, что вы можете выбрать способ, которым вы хотите:
-
Более быстрый способ (т.е. путь C), но вы должны быть уверены, что код является узким местом в вашем приложении (преждевременные оптимизации - это зло и т.д.) и что ваш код надежно инкапсулирован, чтобы избежать риска переполнения буфера.
-
Более безопасный способ (т.е. способ С++), если вы знаете, что эта часть кода не является критичной, поэтому убедитесь, что эта часть кода не будет прерываться в случайные моменты, потому что кто-то ошибочно принял размер или указатель (который происходит в реальной жизни, например... вчера, на моем компьютере, потому что кто-то подумал, что "круто" использовать более быстрый способ, не нуждаясь в этом).
Ответ 4
Попробуйте sprintf():
char str[12];
int num = 3;
sprintf(str, "%d", num); // str now contains "3"
sprintf() подобен printf(), но выводится в строку.
Кроме того, как упоминалось в комментариях Parappa, вы можете использовать snprintf(), чтобы остановить переполнение буфера (где число, которое вы конвертируете, не соответствует размеру вашей строки.) Это работает так
snprintf(str, sizeof(str), "%d", num);
Ответ 5
За кулисами lexical_cast делает это:
std::stringstream str;
str << myint;
std::string result;
str >> result;
Если вы не хотите "перетаскивать" boost для этого, то использование вышеописанного является хорошим решением.
Ответ 6
Мы можем определить нашу собственную функцию iota
в С++ как:
string itoa(int a)
{
string ss=""; //create empty string
while(a)
{
int x=a%10;
a/=10;
char i='0';
i=i+x;
ss=i+ss; //append new character at the front of the string!
}
return ss;
}
Не забудьте #include <string>
.
Ответ 7
Вот C-версия itoa, с некоторыми условиями:
char* custom_itoa(int i)
{
static char output[24]; // 64-bit MAX_INT is 20 digits
char* p = &output[23];
for(*p--=0;i;i/=10) *p--=i%10+0x30;
return ++p;
}
- Это не обрабатывает отрицательные числа
- В настоящее время это не обрабатывает числа, превышающие 23 символа в десятичной форме.
- он не является потокобезопасным
- возвращаемое значение будет стерто/повреждено, как только функция будет вызвана снова.
Итак, если вы собираетесь сохранить возвращаемое значение, вам нужно strcpy
его в отдельный буфер.
Ответ 8
C++ 11, наконец, разрешает это предоставление std::to_string
.
Также boost::lexical_cast
- удобный инструмент для старых компиляторов.
Ответ 9
Я использую эти шаблоны
template <typename T> string toStr(T tmp)
{
ostringstream out;
out << tmp;
return out.str();
}
template <typename T> T strTo(string tmp)
{
T output;
istringstream in(tmp);
in >> output;
return output;
}
Ответ 10
Попробуйте Boost.Format или FastFormat, как высококачественные библиотеки С++:
int i = 10;
std::string result;
WIth Boost.Format
result = str(boost::format("%1%", i));
или FastFormat
fastformat::fmt(result, "{0}", i);
fastformat::write(result, i);
Очевидно, что оба они делают намного больше, чем простое преобразование целого числа
Ответ 11
Фактически вы можете преобразовать что-либо в строку с помощью одной умственно написанной функции шаблона. В этом примере кода используется цикл для создания подкаталогов в системе Win32. Оператор конкатенации строк, оператор +, используется для объединения корня с суффиксом для генерации имен каталогов. Суффикс создается путем преобразования переменной управления циклом я в строку С++ с использованием функции шаблона и конкатенацией с другой строкой.
//Mark Renslow, Globe University, Minnesota School of Business, Utah Career College
//C++ instructor and Network Dean of Information Technology
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // string stream
#include <direct.h>
using namespace std;
string intToString(int x)
{
/**************************************/
/* This function is similar to itoa() */
/* "integer to alpha", a non-standard */
/* C language function. It takes an */
/* integer as input and as output, */
/* returns a C++ string. */
/* itoa() returned a C-string (null- */
/* terminated) */
/* This function is not needed because*/
/* the following template function */
/* does it all */
/**************************************/
string r;
stringstream s;
s << x;
r = s.str();
return r;
}
template <class T>
string toString( T argument)
{
/**************************************/
/* This template shows the power of */
/* C++ templates. This function will */
/* convert anything to a string! */
/* Precondition: */
/* operator<< is defined for type T */
/**************************************/
string r;
stringstream s;
s << argument;
r = s.str();
return r;
}
int main( )
{
string s;
cout << "What directory would you like me to make?";
cin >> s;
try
{
mkdir(s.c_str());
}
catch (exception& e)
{
cerr << e.what( ) << endl;
}
chdir(s.c_str());
//Using a loop and string concatenation to make several sub-directories
for(int i = 0; i < 10; i++)
{
s = "Dir_";
s = s + toString(i);
mkdir(s.c_str());
}
system("PAUSE");
return EXIT_SUCCESS;
}
Ответ 12
Выделите строку достаточной длины, затем используйте snprintf.
Ответ 13
Лучший ответ, IMO, - это функция, представленная здесь:
http://www.jb.man.ac.uk/~slowe/cpp/itoa.html
Он имитирует функцию, отличную от ANSI, предоставляемую многими библиотеками.
char* itoa(int value, char* result, int base);
Он также молниеносно и хорошо оптимизирован под -O3, и причина, по которой вы не используете С++ string_format()... или sprintf, заключается в том, что они слишком медленные, верно?
Ответ 14
Обратите внимание, что все методы stringstream
могут включать блокировку вокруг использования объекта locale для форматирования. Этот может быть осторожным, если вы используете это преобразование из нескольких потоков...
Подробнее см. здесь. Преобразовать число в строку с указанной длиной в С++
Ответ 15
int number = 123;
stringstream = s;
s << number;
cout << ss.str() << endl;
Ответ 16
На платформах производства Windows CE по умолчанию нет iostream
. Путь туда - предпочтительнее с семейством _itoa<>
, обычно _itow<>
(так как большинство файлов строк - Unicode, все равно).
Ответ 17
Если вы заинтересованы в быстром, а также безопасном целочисленном методе преобразования строк и не ограничиваетесь стандартной библиотекой, я могу рекомендовать метод FormatInt
из Библиотека формата С++:
fmt::FormatInt(42).str(); // convert to std::string
fmt::FormatInt(42).c_str(); // convert and get as a C string
// (mind the lifetime, same as std::string::c_str())
В соответствии с integer для строковых тестов конверсии из Boost Karma этот метод в несколько раз быстрее, чем glibc sprintf
или std::stringstream
. Это даже быстрее, чем Boost Karma int_generator
, как было подтверждено независимым эталоном .
Отказ от ответственности: я являюсь автором этой библиотеки.
Ответ 18
Я написал эту потокобезопасную функцию некоторое время назад, и я очень доволен результатами и считаю, что алгоритм является легким и худым, с производительностью около 3X стандартной функции MSVC _itoa(),
Здесь ссылка. Оптимальная база-10 только функция itoa()? Производительность не менее 10X от sprintf(). Тест также является функцией QA-теста, как показано ниже.
start = clock();
for (int i = LONG_MIN; i < LONG_MAX; i++) {
if (i != atoi(_i32toa(buff, (int32_t)i))) {
printf("\nError for %i", i);
}
if (!i) printf("\nAt zero");
}
printf("\nElapsed time was %f milliseconds", (double)clock() - (double)(start));
Есть несколько глупых предложений относительно использования хранилища вызывающего абонента, которое оставило бы результат, плавающий где-то в буфере в адресном пространстве вызывающего абонента. Игнорируй их. Код, который я перечислял, отлично работает, поскольку демонстрируется эталонный/QA-код.
Я считаю, что этот код достаточно скуден для использования во встроенной среде. YMMV, конечно.
Ответ 19
Большинство из вышеперечисленных предложений технически не являются С++, они являются C-решениями.
Посмотрите на использование std:: stringstream.