提问



在C ++中从int转换为等效string的最简单方法是什么?我知道两种方法。有没有更简单的方法?


(1)


int a = 10;
char *intStr = itoa(a);
string str = string(intStr);


(2)


int a = 10;
stringstream ss;
ss << a;
string str = ss.str();

最佳参考


C ++ 11引入std::stoi(和每种数字类型的变体)和std::to_string,C atoiitoa的对应物,但以std::string表示。]]。[96] [97]


#include <string> 

std::string s = std::to_string(42);


因此,这是我能想到的最短路。您甚至可以使用auto关键字省略命名类型:


auto s = std::to_string(42);


注意:请参阅 [[string.conversions]] (n3242中 21.5 ) [98]

其它参考1


几年后,与@ v.oddou进行了讨论,C ++ 17终于提供了一种方法来完成最初的基于宏的类型无关的解决方案(保存在下面),而不用通过宏uglyness。


template < typename... Args >
std::string sstr( Args &&... args )
{
    std::ostringstream sstr;
    ( sstr << std::dec << ... << args );
    return sstr.str();
}


用法:


int i = 42;
std::string s = sstr( "i is: ", i );
puts( sstr( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( sstr( "Foo is '", x, "', i is ", i ) );





原始回答:


由于将...转换为字符串是一个反复出现的问题,我总是在我的C ++源代码的中心标题中定义SSTR()宏:[99]


#include <sstream>

#define SSTR( x ) static_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()


用法很简单:


int i = 42;
std::string s = SSTR( "i is: " << i );
puts( SSTR( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( SSTR( "Foo is '" << x << "', i is " << i ) );


以上是C ++ 98兼容(如果你不能使用C ++ 11 std::to_string),并且不需要任何第三方包含(如果你不能使用Boost lexical_cast<>);这些其他解决方案都有更好的性能。

其它参考2


我通常使用以下方法:


#include <sstream>

template <typename T>
  std::string NumberToString ( T Number )
  {
     std::ostringstream ss;
     ss << Number;
     return ss.str();
  }


这里详细描述。[100]

其它参考3


可能最常见的简单方法基本上将您的第二个选择包装到名为lexical_cast的模板中,例如Boost中的模板,因此您的代码如下所示:[101]


int a = 10;
string s = lexical_cast<string>(a);


这样做的一个好处是它也支持其他演员表(例如,在相反的方向上也可以工作)。


另请注意,尽管Boost lexical_cast最初只是写入字符串流,然后从流中提取出来,但它现在还有一些补充。首先,添加了很多类型的特化,因此对于许多常见类型,它比使用字符串流快得多。其次,它现在检查结果,所以(例如)如果从字符串转换为int,如果字符串包含无法转换为int的内容,它可以抛出异常(例如,1234会成功,但123abc会抛出) 。


从C ++ 11开始,有一个std::to_string函数为整数类型重载,所以你可以使用如下代码:


int a = 20;
std::string s = to_string(a);


标准将这些定义为等同于使用sprintf进行转换(使用与提供的对象类型匹配的转换说明符,例如int%d)到足够的缓冲区中大小,然后创建该缓冲区内容的std::string

其它参考4


如果你安装了Boost(你应该):


#include <boost/lexical_cast.hpp>

int num = 4;
std::string str = boost::lexical_cast<std::string>(num);

其它参考5


使用stringstreams会不会更容易?


#include <sstream>

int x=42;            //The integer
string str;          //The string
ostringstream temp;  //temp as in temporary
temp<<x;
str=temp.str();      //str is temp as string


或者做一个功能:


#include <sstream>

string IntToString (int a)
{
    ostringstream temp;
    temp<<a;
    return temp.str();
}

其它参考6


在纯C ++中,我不知道。但对你提到的内容进行一点修改


string s = string(itoa(a));


应该工作,而且很短。

其它参考7


sprintf()非常适合格式转换。然后,您可以像在1中一样将生成的C字符串分配给C ++字符串。

其它参考8


首先包括:


#include <string>
#include <sstream>


第二个添加方法:


template <typename T>
string NumberToString(T pNumber)
{
 ostringstream oOStrStream;
 oOStrStream << pNumber;
 return oOStrStream.str();
}


使用这样的方法:


NumberToString(69);


要么


int x = 69;
string vStr = NumberToString(x) + " Hello word!."

其它参考9


您可以按照Matthieu M.的建议使用C ++ 11中提供的std::to_string:


std::to_string(42);


或者,如果性能至关重要(例如,如果进行大量转换),则可以使用C ++格式库中的fmt::FormatInt将整数转换为std::string:[103]


fmt::FormatInt(42).str();


或C字符串:


fmt::FormatInt f(42);
f.c_str();


后者不做任何动态内存分配,并且比Boost Karma基准测试的std::to_string快10倍。请参阅 C ++中的快速整数到字符串转换以获取更多详细信息。[104]


std::to_string不同,fmt::FormatInt不需要C ++ 11并且可以与任何C ++编译器一起使用。


免责声明:我是C ++格式库的作者。

其它参考10


使用stringstream进行数字转换非常危险!


见http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/,它告诉operator<<插入格式化输出。[105]


根据您当前的区域设置,大于3位的整数,可以转换为4位数的字符串,添加额外的千位分隔符。


例如,int = 1000可以转换为字符串1.001。这可能使比较操作根本不起作用。


所以我强烈建议使用std::to_string方式。它更容易,做你期望的。

其它参考11


对于C ++ 98 ,有几个选项:


boost/lexical_cast



Boost不是C ++库的一部分,但包含许多有用的库扩展。



  lexical_cast函数模板提供了一种方便且一致的形式,用于支持在任意类型表示为文本时的常见转换。点击
   - 提升文件[106]



#include "boost/lexical_cast.hpp"
#include <string>

int main() {
    int x = 5;
    std::string x_str = boost::lexical_cast<std::string>(x);
    return 0;
}


至于运行时,lexical_cast操作在第一次转换时需要大约80微秒(在我的机器上),然后如果冗余完成则会大大加快。





itoa




  此函数未在ANSI-C中定义,并且不是C ++的一部分,但是受到某些编译器的支持。点击
   - cplusplus.com [107]



这意味着gcc/g++无法使用itoa编译代码。


#include <stdlib.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    x_str = itoa(x, x_str, 10); // base 10
    return 0;
}


没有运行时报告。我没有安装Visual Studio,据说可以编译itoa





sprintf



sprintf是一个C标准库函数,适用于C字符串,是一个完全有效的选择。



  如果在printf上使用了格式,则使用与打印时相同的文本组成一个字符串,但不是打印,而是将内容作为C字符串存储在str指向的缓冲区中。点击
   - cplusplus.com [109]



#include <stdio.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    int chars_written = sprintf(x_str, "%d", x);
    return 0;
}


stdio.h标题可能没有必要。至于运行时,sprintf操作在第一次转换时大约需要40微秒(在我的机器上),然后如果冗余完成则会大大加快。





stringstream



这是C ++库将整数转换为字符串的主要方式,反之亦然。stringstream有类似的姐妹函数,它们进一步限制了流的预期用途,如ostringstreamostringstream具体告诉读者你的代码只打算使用<<运算符。这个函数是将整数转换为字符串所特有的。请参阅此问题以进行更详细的讨论。


#include <sstream>
#include <string>

int main() {
    int x = 5;
    std::ostringstream stream;
    stream << x;
    std::string x_str = stream.str();
    return 0;
}


至于运行时,ostringstream操作大约需要71微秒(在我的机器上),然后如果冗余完成则会大大加快,但不如前面的功能。





当然还有其他选择,您甚至可以将其中一个包装到您自己的功能中,但这可以分析一些流行的功能。

其它参考12


使用:


#define convertToString(x) #x

int main()
{
    convertToString(42); // Returns const char* equivalent of 42
}

其它参考13


添加一些语法糖是相当容易的,它允许人们以类似流的方式动态组合字符串


#include <string>
#include <sstream>

struct strmake {
    std::stringstream s;
    template <typename T> strmake& operator << (const T& x) {
        s << x; return *this;
    }   
    operator std::string() {return s.str();}
};


现在你可以追加你想要的任何东西(假设为它定义了一个运算符<< (std::ostream& ..))到strmake()并用它来代替std::string


例:


#include <iostream>

int main() {
    std::string x =
      strmake() << "Current time is " << 5+5 << ":" << 5*5 << " GST";
    std::cout << x << std::endl;
}

其它参考14


namespace std
{
    inline string to_string(int _Val)
    {   // convert long long to string
        char _Buf[2 * _MAX_INT_DIG];
        snprintf(_Buf, "%d", _Val);
        return (string(_Buf));
    }
}


你现在可以用to_string(5)

其它参考15


我用:


int myint = 0;
long double myLD = 0.0;

string myint_str = static_cast<ostringstream*>( &(ostringstream() << myint) )->str();
string myLD_str = static_cast<ostringstream*>( &(ostringstream() << myLD) )->str();


它适用于我的windows和linux g ++编译器。

其它参考16


使用CString:


int a = 10;
CString strA;
strA.Format("%d", a);

其它参考17


string number_to_string(int x){
    if(!x) return "0";
        string s,s2;
        while(x){
            s.push_back(x%10 + '0');
            x/=10;
        }
    reverse(s.begin(),s.end());
    return s;
}

其它参考18


#include "stdafx.h"
#include<iostream>
#include<string>
#include<string.h>


std::string intToString(int num);

int main()
{

    int integer = 4782151;

    std::string integerAsStr = intToString(integer);

    std::cout << "integer = " << integer << std::endl;
    std::cout << "integerAsStr = " << integerAsStr << std::endl;


    return 0;
}

std::string intToString(int num)
{
    std::string numAsStr;

    while (num)
    {
        char toInsert = (num % 10) + 48;
        numAsStr.insert(0, 1, toInsert);

        num /= 10;
    }

    return numAsStr;
}

其它参考19


char * bufSecs = new char[32];
char * bufMs = new char[32];
sprintf(bufSecs,"%d",timeStart.elapsed()/1000);
sprintf(bufMs,"%d",timeStart.elapsed()%1000);

其它参考20


如果您需要将具有固定位数的整数快速转换为char * left-padded with0,这是一个方便的示例:


int n = 27;
char s[8];


如果要转换两位数字:


*(int32_t*)s = 0x3030 | (n/10) | (n%10) << 8;


如果要转换三位数字:


*(int32_t*)s = 0x303030 | (n/100) | (n/10%10) << 8 | (n%10) << 16;


如果要转换四位数字:


*(int64_t*)s = 0x30303030 | (n/1000) | (n/100%10)<<8 | (n/10%10)<<16 | (n%10)<<24;


以及最多七位数的数字:)

其它参考21



  这是另一种简单的方法



char str[100] ; 
sprintf(str , "%d" , 101 ) ;  
string s = str; 


sprintf是众所周知的将数据插入所需格式的字符串。


您可以将char *数组转换为字符串,如第三行所示。

其它参考22


int n = 123;
std::string str = std::to_string(n);

其它参考23


您使用计数器类型的算法转换为字符串。我从Commodore 64计算机编程中获得了这项技术。它也适合游戏编程。[111]



  • 取整数并取每个由10的幂加权的数字。因此假设整数为950。



    • 如果整数等于或大于100,000,则减去100,000并在[[000000]]处增加字符串中的计数器;

      继续这样做,直到没有更多的数字在100,000位置。
      再降10点力量

    • 如果整数等于或大于10,000,则减去10,000并增加[[000000]] + 1位置的字符串中的计数器;点击
      继续这样做,直到位置10,000没有更多数字。


  • 再次降低10的力量

  • 重复模式



我知道950太小了不能用作例子,但我希望你能得到这个想法。