Альтернатива itoa() для преобразования целого числа в строку C++?

Мне было интересно, если есть альтернатива itoa() для преобразования целого числа в строку, потому что когда я запускаю его в Visual Studio, я получаю предупреждения, а когда я пытаюсь собрать свою программу под Linux, я получаю ошибку компиляции.

18 ответов

Решение

В 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, который вы можете ввести с помощью defdef для snprintf, если вам это нужно).

С ++.

Используйте потоки 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;

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

Мы можем определить наши собственные 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>,

С++11 наконец-то разрешает это обеспечение std::to_string, Также boost::lexical_cast это удобный инструмент для старых компиляторов.

Я использую эти шаблоны

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

Вот 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 это в отдельный буфер.

Попробуйте Boost.Format или FastFormat, обе высококачественные библиотеки C++:

int i = 10;
std::string result;

С Boost.Format

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

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

Я написал эту поточно-ориентированную функцию некоторое время назад, и я очень доволен результатами и чувствую, что алгоритм является легким и экономичным, с производительностью, примерно в 3 раза превышающей стандартную функцию MSVC _itoa().

Вот ссылка. Оптимальная функция Base-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));

Есть несколько глупых предложений, касающихся использования хранилища вызывающего, из-за которого результат остается где-то в буфере в адресном пространстве вызывающего. Игнорируй их. Код, который я перечислил, работает отлично, как показывает код тестирования / тестирования.

Я считаю, что этот код достаточно прост для использования во встроенной среде. YMMV, конечно.

int number = 123;

stringstream = s;

s << number;

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

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

http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

Он имитирует не-ANSI функцию, предоставляемую многими библиотеками.

char* itoa(int value, char* result, int base);

Это также молниеносно и хорошо оптимизирует под -O3, и причина, по которой вы не используете C++ string_format() ... или sprintf, в том, что они слишком медленные, верно?

Если вы заинтересованы в быстром и безопасном методе преобразования целых чисел в строку и не ограничены стандартной библиотекой, я могу порекомендовать 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, Это даже быстрее, чем собственный Boost Karma int_generator как было подтверждено независимым тестом.

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

Обратите внимание, что все stringstream методы могут включать блокировку использования объекта языкового стандарта для форматирования. Это может вызывать опасения, если вы используете это преобразование из нескольких потоков...

Смотрите здесь для получения дополнительной информации. Преобразовать число в строку указанной длины в C++

На платформе, производной от Windows CE, нет iostreamпо умолчанию. Путь туда предпочтительнее с _itoa<> семья, как правило, _itow<> (поскольку в любом случае большинство строковых файлов - это Unicode).

Большинство из приведенных выше предложений технически не являются C++, а являются решениями на C.

Посмотрите на использование std:: stringstream.

Другие вопросы по тегам