How to convert a number to string and vice versa in C++
因为这个问题每周都会被问到,所以这个常见问题解答可能会帮助很多用户。
如何在C++中将整数转换为字符串
如何将字符串转换成C++中的整数
如何在C++中将浮点数转换为字符串
如何在C++中将字符串转换为浮点数
C++ 11的更新
从
1 2 3 4 5 6 7 8 | float stof(const string& str, size_t *idx = 0); double stod(const string& str, size_t *idx = 0); long double stold(const string& str, size_t *idx = 0); int stoi(const string& str, size_t *idx = 0, int base = 10); long stol(const string& str, size_t *idx = 0, int base = 10); unsigned long stoul(const string& str, size_t *idx = 0, int base = 10); long long stoll(const string& str, size_t *idx = 0, int base = 10); unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10); |
其中每一个都以一个字符串作为输入,并尝试将其转换为数字。如果无法构造有效的数字,例如因为没有数字数据或数字超出类型的范围,则会引发异常(
如果转换成功且
最后,整数类型允许指定一个基数,对于大于9的数字,假定使用字母表(
最后,对于每个函数,还有一个重载,它接受一个
1 2 3 4 5 6 7 8 9 | string to_string(int val); string to_string(unsigned val); string to_string(long val); string to_string(unsigned long val); string to_string(long long val); string to_string(unsigned long long val); string to_string(float val); string to_string(double val); string to_string(long double val); |
更简单的方法是,传递适当的数字类型,然后返回一个字符串。对于格式化选项,您应该返回到C++ 03 StrugsRAME选项,并使用流操作器,如这里的另一个答案所解释的。
如注释中所述,这些函数返回到默认尾数精度,该精度可能不是最大精度。如果应用程序需要更高的精度,最好返回到其他字符串格式设置过程。
还定义了类似的函数,命名为
如何在C++ 03中将数字转换为字符串
使用字符串流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <sstream> //include this to use string streams #include <string> int main() { int number = 1234; std::ostringstream ostr; //output string stream ostr << number; //use the string stream just like cout, //except the stream prints not to stdout but to a string. std::string theNumberString = ostr.str(); //the str() function of the stream //returns the string. //now theNumberString is"1234" } |
注意,也可以使用字符串流将浮点数字转换为字符串,还可以根据需要格式化字符串,就像使用
1 2 3 4 5 6 | std::ostringstream ostr; float f = 1.2; int i = 3; ostr << f <<" +" i <<" =" << f + i; std::string s = ostr.str(); //now s is"1.2 + 3 = 4.2" |
可以使用流操纵器,如
不要混淆
使用增强词法。如果你不熟悉Boost,最好从这个词汇库开始。要下载并安装Boost及其文档,请访问此处。虽然Boost不是C++标准,但许多Boost库最终得到了标准化,Boost被广泛认为是最好的C++库。
词法转换在下面使用流,所以基本上这个选项与前一个选项相同,只是不那么冗长。
1 2 3 4 5 6 7 8 9 10 | #include <boost/lexical_cast.hpp> #include <string> int main() { float f = 1.2; int i = 42; std::string sf = boost::lexical_cast<std::string>(f); //sf is"1.2" std::string si = boost::lexical_cast<std::string>(i); //sf is"42" } |
如何将字符串转换成C++ 03中的数字
继承自C的最轻量选项是函数
1 2 3 4 5 6 7 8 9 | #include <cstdlib> //the standard C library header #include <string> int main() { std::string si ="12"; std::string sf ="1.2"; int i = atoi(si.c_str()); //the c_str() function"converts" double f = atof(sf.c_str()); //std::string to const char* } |
使用字符串流(这次输入字符串流,
1 2 3 4 5 6 7 8 9 10 11 | #include <sstream> #include <string> int main() { std::string inputString ="1234 12.3 44"; std::istringstream istr(inputString); int i1, i2; float f; istr >> i1 >> f >> i2; //i1 is 1234, f is 12.3, i2 is 44 } |
使用增强词法。
1 2 3 4 5 6 7 8 9 10 | #include <boost/lexical_cast.hpp> #include <string> int main() { std::string sf ="42.2"; std::string si ="42"; float f = boost::lexical_cast<float>(sf); //f is 42.2 int i = boost::lexical_cast<int>(si); //i is 42 } |
如果输入错误,
STD:C++17中,新函数STD::To-CARS和STD::FROX-CHARS被引入到头查尔考夫中。
std::to_chars is locale-independent, non-allocating,
and non-throwing.Only a small subset of formatting policies used by
other libraries (such as std::sprintf) is provided.
从STD::to-CARS,与STD::Fux-CARS。
The guarantee that std::from_chars can recover
every floating-point value formatted
by to_chars exactly is only provided if both
functions are from the same implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // See en.cppreference.com for more information, including format control. #include <cstdio> #include <cstddef> #include <cstdlib> #include <cassert> #include <charconv> using Type = /* Any fundamental type */ ; std::size_t buffer_size = /* ... */ ; [[noreturn]] void report_and_exit(int ret, const char *output) noexcept { std::printf("%s ", output); std::exit(ret); } void check(const std::errc &ec) noexcept { if (ec == std::errc::value_too_large) report_and_exit(1,"Failed"); } int main() { char buffer[buffer_size]; Type val_to_be_converted, result_of_converted_back; auto result1 = std::to_chars(buffer, buffer + buffer_size, val_to_be_converted); check(result1.ec); *result1.ptr = '\0'; auto result2 = std::from_chars(buffer, result1.ptr, result_of_converted_back); check(result2.ec); assert(val_to_be_converted == result_of_converted_back); report_and_exit(0, buffer); } |
虽然编译器没有完全实现它,但它肯定会被实现。
我从StackOverflow的某个地方偷了这个便利类,将任何可流式转换为字符串:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // make_string class make_string { public: template <typename T> make_string& operator<<( T const & val ) { buffer_ << val; return *this; } operator std::string() const { return buffer_.str(); } private: std::ostringstream buffer_; }; |
然后你用它作为;
1 | string str = make_string() << 6 << 8 <<"hello"; |
相当漂亮!
另外,我使用这个函数将字符串转换成任何可流式的,尽管如果您试图解析一个不包含数字的字符串是不太安全的;(它也不像最后一个那么聪明)
1 2 3 4 5 6 7 8 9 | // parse_string template <typename RETURN_TYPE, typename STRING_TYPE> RETURN_TYPE parse_string(const STRING_TYPE& str) { std::stringstream buf; buf << str; RETURN_TYPE val; buf >> val; return val; } |
用作:
1 | int x = parse_string<int>("78"); |
您可能还需要wstring的版本。