我想知道是否有将整数转换为字符串的替代方法,itoa()
因为当我在 Visual Studio 中运行它时会收到警告,而当我尝试在 Linux 下构建程序时,会出现编译错误。
18 回答
在 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方式
使用 sprintf。或 snprintf。或者你找到的任何工具。
尽管某些函数不在标准中,正如“onebyone”在他的一个评论中正确提到的那样,大多数编译器都会为您提供替代方案(例如,Visual C++ 有自己的 _snprintf,如果需要,您可以将其 typedef 到 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;
如果您不想为此“拖入”提升,那么使用上述方法是一个很好的解决方案。
我们可以iota
在 C++ 中定义我们自己的函数:
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;
使用 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;
}
分配一个足够长的字符串,然后使用 snprintf。
int number = 123;
stringstream = s;
s << number;
cout << ss.str() << endl;
如果您对快速且安全的整数到字符串的转换方法感兴趣并且不限于标准库,我可以推荐{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 的整数到字符串转换基准,这种方法比 glibcsprintf
或std::stringstream
. 正如独立基准int_generator
所证实的那样,它甚至比 Boost Karma 自己的还要快。
免责声明:我是这个库的作者。
我前段时间写了这个线程安全的函数,对结果很满意,感觉算法轻巧精简,性能大约是标准 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 的原因是它们太慢了,对吧?
请注意,所有stringstream
方法都可能涉及锁定使用区域设置对象进行格式化。如果您从多个线程中使用这种转换,这可能是需要注意的事情......
请参阅此处了解更多信息。在 C++ 中将数字转换为具有指定长度的字符串
在 Windows CE 派生平台上,默认情况下没有iostream
s。去那里的方法_itoa<>
通常是与家人一起去_itow<>
(因为无论如何大多数字符串都是Unicode)。
大多数上述建议在技术上不是 C++,它们是 C 解决方案。
研究std::stringstream的使用。