Альтернатива itoa () для преобразования целого числа в строку C++? [дубликат]
этот вопрос уже есть ответ здесь:
мне было интересно, есть ли альтернатива itoa() для преобразования целого числа в строку, потому что когда я запускаю его в visual Studio, я получаю предупреждения, и когда я пытаюсь построить свою программу под Linux, я получаю ошибка компиляции.
19 ответов:
В C++11 вы можете использовать
std::to_string:#include <string> std::string s = std::to_string(5);Если вы работаете с до C++11, вы можете использовать потоки C++:
#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/
boost:: lexical_cast работает довольно хорошо.
#include <boost/lexical_cast.hpp> int main(int argc, char** argv) { std::string foo = boost::lexical_cast<std::string>(argc); }
Археология
itoa была нестандартной вспомогательной функцией, предназначенной для дополнения стандартной функции atoi и, вероятно, скрывающей sprintf (большинство ее функций могут быть реализованы в терминах sprintf):http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html
Путь C
используйте sprintf. Или snprintf. Или любой инструмент, который вы ищите.
несмотря на то, что некоторые функции не входят в стандарт, как справедливо отметил "onebyone" в одном из своих комментариев, большинство компиляторов предложит вам альтернативу (например, Visual C++ имеет свой собственный _snprintf вы можете typedef в snprintf, если вам это нужно).
путь C++.
используйте потоки C++ (в текущем случае std::stringstream (или даже устаревший std::strstream, как предложил Херб Саттер в одной из своих книг, потому что это несколько быстрее).
вывод
вы находитесь в C++, что означает, что вы можете выбрать, как вы хотите это:
быстрый способ (т. е. способ C), но вы должны быть уверены, что код является узким местом в вашем приложении (преждевременная оптимизация-зло, и т. д.) и что ваш код надежно инкапсулирован, чтобы избежать риска переполнения буфера.
более безопасный способ (т. е. способ C++), если вы знаете, что эта часть кода не критична, поэтому лучше убедиться, что эта часть кода не сломается в случайные моменты, потому что кто-то ошибся размером или указателем (который такое случается в реальной жизни... вчера, на моем компьютере, потому что кто-то подумал, что это "круто" использовать более быстрый способ, не нуждаясь в нем).
попробуйте sprintf ():
char str[12]; int num = 3; sprintf(str, "%d", num); // str now contains "3"sprintf() похож на printf (), но выводит в строку.
snprintf(str, sizeof(str), "%d", num);
за кулисами, lexical_cast это:
std::stringstream str; str << myint; std::string result; str >> result;Если вы не хотите, чтобы "перетащить" импульс для этого, то использование выше является хорошим решением.
мы можем определить наш собственный
iotaфункция в c++ как: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>.
С++11 наконец-то решает эту проблему
std::to_string. Такжеboost::lexical_cast- это удобный инструмент для старых компиляторов.
вот 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это в отдельный буфер.
Я использую эти шаблоны
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; }
попробовать импульс.Формат или FastFormat, обе высококачественные библиотеки C++:
int i = 10; std::string result;С Boost.Формат
result = str(boost::format("%1%", i));или FastFormat
fastformat::fmt(result, "{0}", i); fastformat::write(result, i);очевидно, что они оба делают намного больше, чем простое преобразование одного целого
вы можете фактически преобразовать что-либо в строку с помощью одной умно написанной функции шаблона. В этом примере кода используется цикл для создания подкаталогов в системе Win-32. Оператор объединения строк operator+ используется для объединения корня с суффиксом для создания имен каталогов. Суффикс создается путем преобразования переменной управления циклом i в строку C++ с помощью функции шаблона и объединения ее с другой строкой.
//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; }
лучший ответ, ИМО, это функция, представленная здесь:
http://www.jb.man.ac.uk / ~slowe/cpp/itoa.html
он имитирует функцию non-ANSI, предоставляемую многими библиотеками.
char* itoa(int value, char* result, int base);это также молниеносно и оптимизирует хорошо под-O3, и причина, по которой вы не используете c++ string_format() ... или sprintf - это то, что они слишком медленные, верно?
обратите внимание, что все
stringstreamметоды мая включить блокировку вокруг использования объекта locale для форматирования. Это мая будьте осторожны, если вы используете это преобразование из нескольких потоков...смотрите здесь для получения дополнительной информации. преобразовать число в строку с указанной длиной в C++
если вас интересует быстрый, а также безопасный метод преобразования целого числа в строку и не ограничивается стандартной библиотекой, я могу порекомендовать
FormatIntметод Формат C++ библиотека: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())по словам целочисленные тесты преобразования строк от Boost Karma, этот метод в несколько раз быстрее, чем glibc в
sprintfилиstd::stringstream. Это даже быстрее, чем повысить собственную кармуint_generatorкак было подтвержденонезависимые бенчмарк.отказ от ответственности: я автор этой библиотеки.
Я написал потокобезопасным функция некоторое время назад, и я очень доволен результатами и чувствую, что алгоритм легкий и худой, с производительностью, которая составляет около 3X стандартной функции MSVC _itoa ().
вот ссылка. оптимальная База-10 только функция itoa ()? производительность по крайней мере в 10 раз выше, чем у 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));есть некоторые глупые предложения, сделанные о используя хранилище вызывающего абонента, которое оставило бы результат плавающим где-то в буфере в адресном пространстве вызывающего абонента. Игнорировать их. Код, который я перечислил, отлично работает, как показывает код benchmark/QA.
Я считаю, что этот код достаточно скуден для использования во встроенной среде. МММ, конечно.
на производных платформах Windows CE нет
iostreams по умолчанию. Путь туда есть preferaby с_itoa<>семья, как правило,_itow<>(так как большинство строковых материалов в любом случае являются Unicode).
большинство из вышеперечисленных предложений технически не являются C++, это c-решения.
посмотрите на использование std:: stringstream.
Comments