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

StackOverflow https://stackoverflow.com/questions/228005

  •  03-07-2019
  •  | 
  •  

Вопрос

На этот вопрос уже есть ответ здесь:

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

Это было полезно?

Решение

В 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/

Другие советы

повышение::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

Способ С

Используйте 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 для этого, то использование приведенного выше является хорошим решением.

Мы можем определить наши собственные 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 это удобный инструмент для старых компиляторов.

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

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

int i = 10;
std::string result;

С повышением.Форматировать

result = str(boost::format("%1%", i));

или быстрый формат

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.

Лучший ответ, 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 в том, что они слишком медленные, верно?

Обратите внимание, что все 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())

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

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

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

Вот ссылка. Оптимальная функция itoa() только для базы 10? Производительность как минимум в 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.

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

На платформах, производных от Windows CE, отсутствуют iostreams по умолчанию.Способ попасть туда предпочтительнее всего с _itoa<> семья, обычно _itow<> (поскольку большинство строковых данных там в любом случае в Юникоде).

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top