Альтернатива itoa () для преобразования integer в string 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, который вы можете ввести в 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 (), но выводится в строку.

кроме того, как упоминалось в комментариях Parappa, вы можете использовать snprintf (), чтобы остановить переполнение буфера (где число, которое вы конвертируете, не соответствует размеру вашей строки.) Он работает следующим образом:

snprintf(str, sizeof(str), "%d", num);

за кулисами, lexical_cast это:

std::stringstream str;
str << myint;
std::string result;
str >> result;

Если вы не хотите "перетаскивать" boost для этого, то использование вышеуказанного является хорошим решением.


мы можем определить наши собственные


++ ++ 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++ с помощью функции template и объединения ее с другой строкой.

//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;
}

выделите строку достаточной длины, затем используйте snprintf.


лучший ответ, IMO, - это функция, представленная здесь:

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++


int number = 123;

stringstream = s;

s << number;

cout << ss.str() << endl;

если вас интересует быстрый, а также безопасный метод преобразования целого числа в строку и не ограничивается стандартной библиотекой, я могу порекомендовать 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())

по словам integer в строку преобразования бенчмарков от Boost Karma, этот метод в несколько раз быстрее, чем glibc's sprintf или std::stringstream. Это даже быстрее, чем повысить собственную карму int_generator как было подтвержденонезависимые benchmark.

отказ от ответственности: я автор этой библиотеки.


Я написал потокобезопасным функция некоторое время назад, и я очень доволен результатами и чувствую, что алгоритм легкий и бережливый, с производительностью, которая составляет около 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.