将整数转换为字符串C++的ITOA-()选项

将整数转换为字符串C++的ITOA-()选项,c++,integer,stdstring,itoa,C++,Integer,Stdstring,Itoa,我想知道是否有一种替代itoa的方法可以将整数转换为字符串,因为当我在visual Studio中运行它时,会收到警告,当我尝试在Linux下构建程序时,会出现编译错误。工作得很好 #include <boost/lexical_cast.hpp> int main(int argc, char** argv) { std::string foo = boost::lexical_cast<std::string>(argc); } 试试sprintf: cha

我想知道是否有一种替代itoa的方法可以将整数转换为字符串,因为当我在visual Studio中运行它时,会收到警告,当我尝试在Linux下构建程序时,会出现编译错误。

工作得很好

#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
    std::string foo = boost::lexical_cast<std::string>(argc);
}
试试sprintf:

char str[12];
int num = 3;
sprintf(str, "%d", num); // str now contains "3"
sprintf类似于printf,但输出为字符串

此外,正如Parapa在评论中提到的,如果要转换的数字与字符串大小不符,则可能需要使用snprintf来阻止缓冲区溢出。它的工作原理如下:

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

分配一个足够长的字符串,然后使用snprintf。

在C++11中,您可以使用:

如果你在C++ 11之前工作,你可以使用C++流:

#include <sstream>

int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();

<>从

< P>技术上的建议大多不是C++,它们是C解决方案。
看看。

在幕后,词法演员会这样做:

std::stringstream str;
str << myint;
std::string result;
str >> result;
如果您不想在boost中进行此操作,那么使用上述方法是一个很好的解决方案。

请注意,所有stringstream方法都可能涉及锁定使用locale对象进行格式化。如果您使用来自多个线程的转换,这可能是需要小心的

更多信息请参见此处

考古学 itoa是一个非标准的辅助函数,旨在补充atoi标准函数,可能隐藏了sprintf。它的大多数功能都可以用sprintf实现:

C路 使用sprintf。或snprintf。或者你找到的任何工具

尽管有些功能不在标准中,正如他在一篇评论中正确提到的,大多数编译器会给你一个替代方案,例如VisualC++有自己的ySNPrTNF,如果需要的话,你可以将TyPulf给SNPRTNF。 C++方式。

在当前的情况下使用C++流:STRIGWATH,甚至是弃用的STD::STRSTROW,正如Habor萨特在他的一本书中提出的,因为它有点快。 结论 <>你在C++中,这意味着你可以选择你想要的方式:

更快的方式,即C方式,但是您应该确保代码是应用程序中的瓶颈。过早优化是有害的,等等。并且您的代码被安全地封装,以避免缓冲区溢出的风险

更安全的方式,即C++方式,如果你知道代码的这一部分并不重要,那么最好确保代码的这部分不会在随机的时刻中断,因为有人误认为在现实生活中发生的大小或指针,比如…昨天,在我的电脑上,因为有人认为在没有真正需要的情况下使用更快的方式很酷


在Windows CE衍生平台上,默认情况下没有IOStream。去那里的方式比iToA族好,通常是iToW,因为大多数字符串都是Unicode。无论如何,

< P>试着,或者两个高质量的C++库:

int i = 10;
std::string result;
使用Boost.Format

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;
}
我使用这些模板

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

С++11最终解决了这一问题。 另外,BooLoCySCAST是旧编译器的一种方便工具。

< P>我们可以在C++中定义我们自己的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;
}

不要忘了包括。

如果您对快速安全的整数到字符串转换方法感兴趣,并且不限于标准库,我可以从库中推荐format_int方法:

根据Boost Karma的研究,这种方法比glibc的sprintf或std::stringstream快几倍。它甚至比Boost Karma自己的int_生成器还要快,这一点已被一位专家证实

免责声明:我是这个库的作者。

我不久前编写了这个线程安全函数,我对结果非常满意,并且觉得该算法是轻量级和精简的,性能大约是标准MSVC_itoa函数的3倍

这是链接。性能至少是sprintf的10倍。基准测试也是功能的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));
关于使用调用者的存储器,有一些愚蠢的建议会使结果漂浮在调用者地址空间的缓冲区中的某个地方。别理他们。正如基准/QA代码所示,我列出的代码工作得非常好


我相信这段代码足够精练,可以在嵌入式环境中使用。当然是YMMV。

最好的答案,IMO,是这里提供的功能:

它模仿许多lib提供的非ANSI函数

char* itoa(int value, char* result, int base);
它也闪电般的快,并且在-O3和t下优化得很好

他认为你不使用C++ StRIGIX格式…或者Spavtf是它们太慢了,对吗?< /P> SeaTrf不是C++。它是C。您应该使用snprintf来避免缓冲区溢出。在上面的示例中,这只是一行更改:snprintfstr,sizeofstr,%d,num;IMHO STRIGWORD将是一个更好的选择。OJ:Simultf也是C++…大多数C语言都是C++语言编写的。这不是意外。C++是C++上的一个层。不是一个定义的体系结构,比如它可能是一个错误,因为它是STR函数的一种类型:SpRAPTF是“STR”,但是问题应该是“String”。@ OJ:技术上不是C++——这是挑剔和进一步挑剔的,因为有一个提到大多数都是C++技术。特别是因为OP正在寻找一个没有警告的itoa替代品。基本上与这个问题相反。答案是一样的。下面的例子是如何的:它们非常高效,有些优雅。你可以看到一个比较3种现代的C++方式转换整数到ScRunSi的方法。它是线程安全的,可以处理所有正、负32位整数和零。性能非常好,而且算法非常精简,因此不会占用大量缓存。Ben Voigt有一个更快的方法,但它不是一个轻量级的算法,所以除非你做了数十亿次这样的事情,否则它可能是杀伤力过大。太糟糕了,Windows CE衍生平台默认没有IOStream。去那里的路最好是伊藤家族。你如何清除stringstream?我想你的意思是:stringstream很好,但要知道它可以显著增加可执行文件的大小。使用Boost库进行一次转换:但是如果您已经在使用Boost,那么它是免费的。Boost::lexical_cast的速度非常慢。如果性能很重要,不要使用它。我认为在大多数情况下,担心这是过早的优化。它不会阻止我使用它,除非我的剖析器告诉我,否则。慢得让人痛苦?你从哪儿弄来的?它实际上表现得相当好@克里斯·卡明斯基:我的一项测试确实显示sprintf的速度快了5到10倍,这证实了我的赫伯·萨特自己的测量结果。如果你有不同的测试结果,我很感兴趣。@ Chris Kaminski:如果你研究C++流的接口,你会理解为什么它们会慢,即使输出一个简单的整数:在C中,你使用你自己的缓冲区,可能在堆栈中分配,而在C++中,StrugSukes将使用它自己的。在C语言中,您可以重用缓冲区。在C++中,必须从String String中提取字符串,这是一个STD::String Reopy.@ FuffyTew:谢谢您的关注,但我想我已经足够熟悉C API和C++ API来处理SaveTFF,并且知道何时和如何安全地使用它,并且什么时候不使用它……D@fuzzyTew:1在我的帖子中,我谈到了sprintf及其安全变体,而不仅仅是sprintf。2了解代码的编译位置并不是一项不可能的任务。在我的情况下,最坏的情况是Windows/VC++、Solaris/CC和Linux/g++,最好的情况是仅限Windows/VC++。你描述的是一个破坏者试图破坏你的代码的世界。我的世界是由普通开发人员组成的,因此浪费时间试图通过重写每个API的安全版本来保护我的代码不受破坏是没有效率的。[…]@fuzzyTew:[…]结论使用手头最好的工具。如果最好的工具是隐藏在包装类或函数中的sprintf。。。现在,如果您主张重写sprintf作为这个问题的答案,请随意编写您自己的答案。我不确定问题作者是否阅读了所有的评论。我怀疑当str.str足够时,它是否会流到字符串中。如果lexical_cast这样做,如何解释中的巨大差距?他没有解释在问题中您链接的原因是因为每次都创建stringstream对象吗?这些都很好,但不幸的是缺少错误处理。这是唯一完全回答问题的答案。C++ toSype方法不复制C的ITOA的全部功能,因为它不能处理任意的基。有点让人困惑的是,为什么不包括此功能,特别是考虑到逆函数stoi可以处理任意基。更新链接同一篇文章:
fmt::format_int(42).str();   // convert to std::string
fmt::format_int(42).c_str(); // convert and get as a C string
                             // (mind the lifetime, same as std::string::c_str())
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));
char* itoa(int value, char* result, int base);