首页 文章

用于将整数转换为字符串C的itoa()的替代方案? [重复]

提问于
浏览
136

这个问题在这里已有答案:

我想知道是否有一个替代 itoa() 用于将整数转换为字符串,因为当我在visual Studio中运行它时会收到警告,当我尝试在Linux下构建我的程序时,我收到编译错误 .

18 回答

  • 1

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

  • 1

    boost::lexical_cast效果很好 .

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

    考古学

    itoa是一个非标准的辅助函数,旨在补充atoi标准函数,并且可能隐藏了sprintf(其大部分功能可以用sprintf实现):http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html

    C路

    使用sprintf . 或snprintf . 或者你找到的任何工具 .

    尽管有些函数不在标准中,正如他的一篇评论中“onebyone”正确提到的那样,大多数编译器都会为您提供一个替代方案(例如,Visual C有自己的_snprintf,如果需要,可以输入sndef到snprintf) .

    C路 .

    使用C流(在当前情况下为std :: stringstream(甚至是已弃用的std :: strstream,由Herb Sutter在他的一本书中提出,因为它有点快) .

    结论

    你在C,这意味着你可以选择你想要的方式:

    • 更快的方式(即C方式),但您应该确保代码是应用程序的瓶颈(过早优化是邪恶的等等)并且您的代码被安全封装以避免存在缓冲区溢出的风险 .

    • 更安全的方式(即C方式),如果你知道代码的这一部分并不重要,那么最好确保代码的这一部分不会在随机时刻中断,因为有人误认了大小或指针(发生在现实生活中,比如...昨天,在我的电脑上,因为有人认为使用更快的方式“很酷”而不需要它 .

  • 3

    试试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);
    
  • 46

    在幕后,lexical_cast执行此操作:

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

    如果您不想为此“拖入”提升,那么使用上述方法是一个很好的解决方案 .

  • 10

    我们可以在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;
    }
    

    别忘了 #include <string> .

  • 8

    С11最终解决了这个提供std::to_string . 另外 boost::lexical_cast 是旧编译器的便利工具 .

  • 20

    我使用这些模板

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

    尝试Boost.FormatFastFormat,这两个都是高质量的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);
    

    显然,它们都比单个整数的简单转换做得更多

  • 1

    您可以使用一个巧妙编写的模板函数将任何内容转换为字符串 . 此代码示例使用循环在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;
    }
    
  • 54

    分配足够长度的字符串,然后使用snprintf .

  • -1

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

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

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

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

    它也很闪电并且在-O3下很好地优化,你没有使用c string_format()...或sprintf的原因是它们太慢了,对吧?

  • 2

    请注意,所有 stringstream 方法 may 都涉及锁定使用区域设置对象进行格式化 . 如果你从多个线程使用这个转换,那么 may 要警惕...

    请看这里了解更多 . Convert a number to a string with specified length in C++

  • 0
    int number = 123;
    
    stringstream = s;
    
    s << number;
    
    cout << ss.str() << endl;
    
  • 9

    如果您对快速以及安全的整数到字符串转换方法感兴趣而不仅限于标准库,我可以推荐C++ Format库中的 FormatInt 方法:

    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的integer to string conversion benchmarks,这种方法比glibc的 sprintfstd::stringstream 快几倍 . 它确实比Boost Karma自己的_1301816更快由independent benchmark .

    免责声明:我是这个图书馆的作者 .

  • 6

    我前段时间写了这个 thread-safe 函数,对结果感到非常满意,觉得算法轻巧而且精简,性能大约是标准MSVC _itoa()函数的3倍 .

    这是链接 . Optimal Base-10 only itoa() function?性能至少是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,当然 .

  • 34

    在Windows CE派生的平台上,默认情况下没有 iostream . 去那里的方式优先选择 _itoa<> 系列,通常是 _itow<> (因为大多数字符串的东西都是Unicode) .

  • 1

    上述大多数建议在技术上都不是C,它们是C解决方案 .

    查看std::stringstream的用法 .

相关问题