替代itoa()将整数转换为stringC ++?
我想知道是否有一个替代itoa()
将整数转换为string,因为当我在Visual Studio中运行它,我得到警告,并且当我尝试在Linux下构build我的程序时,我得到一个编译错误。
在C ++ 11中,你可以使用std::to_string
:
#include <string> std::string s = std::to_string(5);
如果你在C ++ 11之前工作,你可以使用C ++stream:
#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。 或者你find的任何工具。
尽pipe有些函数不符合标准,但正如他的一个评论中的“onebyone”正确地提到的那样,大多数编译器会为您提供一个替代scheme(例如Visual C ++有自己的_snprintf,如果需要,可以通过snprintfinput到snprintf)。
C ++的方式。
使用C ++stream(在目前的情况下是std :: stringstream(甚至是Herb Sutter在他的书中提出的std :: strstream),因为它有点快。
结论
你在C ++,这意味着你可以select你想要的方式:
-
更快的方式(即C方式),但你应该确保代码是你的应用程序的瓶颈(过早的优化是邪恶等),并且你的代码被安全地封装,以避免缓冲区溢出的风险。
-
更安全的方法(即C ++方式),如果你知道这部分代码并不重要,那么最好确保这部分代码不会随机破坏,因为有人误认为是大小或指针(这会发生在现实生活中,比如…昨天,在我的电脑上,因为有人认为使用更快的方式而不需要真正的“酷”)。
试试sprintf():
char str[12]; int num = 3; sprintf(str, "%d", num); // str now contains "3"
sprintf()就像printf(),但输出到一个string。
另外,正如Parappa在注释中提到的那样,您可能希望使用snprintf()来阻止发生的缓冲区溢出(您正在转换的数字不适合string的大小)。它的工作原理如下:
snprintf(str, sizeof(str), "%d", num);
在幕后,lexical_cast是这样做的:
std::stringstream str; str << myint; std::string result; str >> result;
如果你不想“拖入”提升这一点,那么使用上述是一个很好的解决scheme。
我们可以在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
也是老版编译器的便利工具。
这是一个itoa的C版本,有一些条件:
char* custom_itoa(int i) { static char output[24]; // 64-bit MAX_INT is 20 digits char* p = &output[23]; for(*p--=0;i;i/=10) *p--=i%10+0x30; return ++p; }
- 这不处理负数
- 这当前不处理十进制forms的大于23个字符的数字。
- 它不是线程安全的
- 一旦函数被再次调用,返回值将被擦除/损坏。
所以如果你要保持返回值,你需要strcpy
到一个单独的缓冲区。
我使用这些模板
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
fastformat::fmt(result, "{0}", i); fastformat::write(result, i);
很明显,他们做的不仅仅是单个整数的简单转换
你可以用一个巧妙的模板函数把任何东西转换成一个string。 此代码示例使用循环在Win-32系统中创build子目录。 string连接运算符operator +用于连接根和后缀以生成目录名称。 后缀是通过将循环控制variablesi转换为C ++string,使用模板函数并将其与另一个string连接而创build的。
//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; }
分配一个足够长的string,然后使用snprintf。
国际海事组织的最佳答案是这里提供的function:
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
方法都可能涉及locking使用区域设置对象进行格式化。 如果你使用multithreading的这种转换,这可能是值得警惕的。
看到这里更多。 将数字转换为C ++中指定长度的string
int number = 123; stringstream = s; s << number; cout << ss.str() << endl;
在Windows CE衍生平台上,默认情况下不存在iostream
。 去那里的方式_itoa<>
系列,通常是_itow<>
(因为大多数string的东西都是Unicode)。
如果您对快速以及安全整数转换为string转换方法感兴趣,而不仅限于标准库,我可以推荐C ++格式库中的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的整数到string转换基准 ,这个方法比glibc的sprintf
或std::stringstream
快几倍。 它比Boost Karma自己的int_generator
还要快,这得到了独立基准的证实。
免责声明:我是这个图书馆的作者。
我前段时间写了这个线程安全函数,对结果非常满意,觉得这个algorithm是轻量级和精简的,性能约为标准MSVC _itoa()函数的3倍。
这是链接。 最佳的Base-10只有itoa()函数? 性能至less是sprintf()的10倍。 基准也是函数的QAtesting,如下所示。
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));
有一些愚蠢的build议使用调用者的存储,将结果浮动在调用者的地址空间缓冲区中的某个地方。 别理他们。 我列出的代码完美地工作,基准/ QA代码演示。
我相信这个代码是足够精简的在embedded式环境中使用。 YMMV,当然。
以上大多数build议在技术上不是C ++,它们是C解决scheme。
看看使用std :: stringstream 。