itoa() 的替代方法,用于将整数转换为字符串C++



我想知道是否有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/

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方式

使用冲刺。或者 snprintf。或者你找到的任何工具。

尽管有些函数不在标准中,正如"onebyone"在他的评论中正确提到的那样,大多数编译器会为您提供替代方案(例如,Visual C++有自己的_snprintf如果需要,您可以键入def到snprintf(。

C++的方式。

使用 C++ 流(在当前情况下为 std::stringstream(甚至是已弃用的 std::strstream,正如 Herb Sutter 在他的一本书中提出的那样,因为它更快一些(。

结论

你在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;

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

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

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

尝试 Boost.Format 或 FastFormat,两者都是高质量的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。

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

我前段时间写了这个线程安全函数,对结果非常满意,感觉算法轻量级和精简,性能大约是标准 MSVC _itoa(( 函数的 3 倍。

这是链接。最佳 Base-10 仅 itoa(( 函数?性能至少是 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 的最佳答案是这里提供的功能:

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

它模仿了许多库提供的非 ANSI 函数。

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

它也快如闪电,并且在 -O3 下进行了很好的优化,而您不使用 c++ 的原因string_format(( ...或者sprintf是它们太慢了,对吧?

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

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())

根据 Boost Karma 的整数到字符串转换基准,这种方法比 glibc 的sprintfstd::stringstream快几倍。它甚至比Boost Karma自己的int_generator更快,正如独立基准所证实的那样。

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

请注意,所有stringstream方法都可能涉及锁定使用区域设置对象进行格式设置。如果您从多个线程使用此转换,这可能是需要警惕的事情......

请参阅此处了解更多信息。将数字转换为具有指定长度的字符串,C++ <</p>

div class="ans>

在 Windows CE 派生平台上,默认情况下没有iostream。去那里的方式最好是_itoa<>家族,通常是_itow<>(因为大多数字符串的东西无论如何都是Unicode(。

从技术上讲,上述大多数建议都不C++,它们是 C 解决方案。

研究一下 std::stringstream 的使用。

相关内容

  • 没有找到相关文章

最新更新