替代 itoa()将整数转换为字符串 C + + ?

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

329539 次浏览

Lexical _ cast 非常好用。

#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 ()类似,但输出为字符串。

另外,正如 Parappa 在注释中提到的,您可能希望使用 snprintf ()来阻止缓冲区溢出的发生(当您正在转换的数字与字符串的大小不匹配时)工作原理是这样的:

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

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

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

上面的大多数建议在技术上都不是 C + + ,而是 C 解决方案。

研究 字符串的使用。

在幕后,lexical _ cast 是这样做的:

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

如果你不想“拖入”这个提升,那么使用以上是一个很好的解决方案。

请注意,所有的 stringstream方法 都涉及锁定使用区域设置对象进行格式化。如果您正在使用来自多个线程的这种转换,那么这个 需要注意..。

详情请参阅此处

考古学

Itoa 是一个非标准的 helper 函数,旨在补充 atoi 标准函数,并且可能隐藏了一个 sprintf (它的大多数特性都可以用 sprintf 来实现) : http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html

C 大道

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

尽管有些函数不符合标准,正如“ onebyone”在他的一篇评论中正确地提到的那样,大多数编译器都会给你提供一个替代方案(例如 Visual C + + 有自己的 _ snprintf,如果你需要的话,你可以把它类型化为 snprintf)。

C + + 的方式。

使用 C + + 流(在当前情况下是 std: : stringstream (或者甚至是已经废弃的 std: : strstream,正如 Herb Sutter 在他的一本书中提出的,因为它有点快)。

结论

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

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

  • 如果你知道这部分代码并不重要,那么最好确保这部分代码不会因为有人弄错了大小或指针而随机中断(这种情况在现实生活中经常发生,比如... ... 昨天,在我的电脑上,因为有人认为使用更快的方法而不是真正需要它是“很酷”的)。

在 WindowsCE 派生的平台上,默认情况下没有 iostream。最好使用 _itoa<>系列,通常是 _itow<>(因为大多数字符串都是 Unicode)。

试试 启动,格式化快速格式,这两个都是高质量的 C + + 库:

int i = 10;
std::string result;

用 Boost. 格式

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

或 FastFormat

fastformat::fmt(result, "{0}", i);
fastformat::write(result, i);

显然,它们都不仅仅是单个整数的简单转换

您实际上可以使用一个巧妙编写的模板函数将任何内容转换为字符串。此代码示例使用循环在 Win-32系统中创建子目录。字符串连接操作符(运算符 +)用于连接带有后缀的根,以生成目录名。后缀是通过使用模板函数将循环控制变量 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;
}
int number = 123;


stringstream = s;


s << number;


cout << ss.str() << endl;

我使用这些模板

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最终解决了这个问题,提供了 std::to_stringboost::lexical_cast也是老编译器的便利工具。

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

如果您对快速且安全的从整数到字符串的转换方法感兴趣,并且不局限于标准库,我可以推荐 { 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更快,独立基准证实了这一点。

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

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

这是链接。最佳基数 -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 代码所示,我列出的代码工作得非常完美。

我相信这段代码足够精简,可以在嵌入式环境中使用。

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 的原因是它们太慢了,对吗?