提问人:Armen Tsirunyan 提问时间:3/13/2011 最后编辑:CommunityArmen Tsirunyan 更新时间:8/10/2023 访问量:172340
如何在 C++ 中将数字转换为字符串,反之亦然
How to convert a number to string and vice versa in C++
问:
由于这个问题每周都会被问到,因此此常见问题解答可能会对很多用户有所帮助。
如何在 C++ 中将整数转换为字符串
如何在 C++ 中将字符串转换为整数
如何在 C++ 中将浮点数转换为字符串
如何在 C++ 中将字符串转换为浮点数
答:
如何在 C++03 中将数字转换为字符串
- 不要使用 or 函数,因为它们是非标准的,因此不可移植。
itoa
itof
使用字符串流
#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" }
请注意,您还可以使用字符串流将浮点数转换为字符串,也可以根据需要设置字符串格式,就像
cout
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"
您可以将流操纵器(如 和 函数 等)与字符串流一起使用,其方式与
std::endl
std::hex
std::setw()
std::setprecision()
cout
不要与 混淆。后者已弃用
std::ostringstream
std::ostrstream
使用增强词法转换。如果你不熟悉 boost,最好从像这样的小型库lexical_cast开始。要下载和安装 boost 及其文档,请访问此处。虽然 boost 不在 C++ 标准中,但许多 boost 库最终都实现了标准化,boost 被广泛认为是最好的 C++ 库。
词法转换使用下面的流,所以基本上这个选项与前一个相同,只是不那么冗长。
#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 的最轻量级选项是函数(用于整数(按字母顺序排列到整数))和(对于浮点值(按字母顺序排列到浮点数))。这些函数将 C 样式的字符串作为参数 (),因此它们的使用可能被认为是一种不太好的 C++ 实践。cplusplus.com 有关于 atoi 和 atof 的易于理解的文档,包括它们在输入错误时的行为方式。但是,该链接包含一个错误,即根据标准,如果输入数字太大而无法适应目标类型,则行为是未定义的。
atoi
atof
const char *
#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* }
使用字符串流(这次输入字符串流,)。同样,istringstream 的使用方式与 .同样,不要与 混淆。后者已弃用。
istringstream
cin
istringstream
istrstream
#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 }
使用增强词法转换。
#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 }
如果输入错误,则抛出 type 的异常
lexical_cast
boost::bad_lexical_cast
评论
atoi
int
INT_MAX
INT_MIN
strtol
atof
strtod
(int)strtol(nptr, (char **)NULL, 10)
istr >> i1 >> f >> i2;
严重错过了成功的支票。
std::to_string
我从 StackOverflow 的某个地方偷走了这个方便的类,将任何可流式传输的内容转换为字符串:
// 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_;
};
然后你把它用作;
string str = make_string() << 6 << 8 << "hello";
相当漂亮!
此外,我使用此函数将字符串转换为任何可流式传输的内容,尽管如果您尝试解析不包含数字的字符串,则它不是很安全;(而且它也不像上一个那么聪明)
// 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;
}
用作:
int x = parse_string<int>("78");
您可能还需要 wstring 的版本。
评论
C++11 更新
作为标准,字符串到数字的转换(反之亦然)内置于标准库中。(根据第21.5段)中存在以下所有功能。C++11
<string>
字符串转数字
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);
它们中的每一个都接受一个字符串作为输入,并尝试将其转换为数字。如果无法构造有效的数字,例如,由于没有数值数据或数字超出类型的范围,则会引发异常 ( 或 )。std::invalid_argument
std::out_of_range
如果转换成功且未成功,则将包含未用于解码的第一个字符的索引。这可能是最后一个字符后面的索引。idx
0
idx
最后,整型允许指定一个基数,对于大于 9 的数字,假定字母表为 ( 直到 )。您可以在此处找到有关可以解析浮点数、有符号整数和无符号整数的确切格式的更多信息。a=10
z=35
最后,对于每个函数,还有一个重载,它接受 a 作为它的第一个参数。std::wstring
数字转字符串
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 stringsream 选项并使用流操纵器,如此处的另一个答案中所述。
如注释中所述,这些函数回退到默认尾数精度,该精度可能不是最大精度。如果您的应用程序需要更高的精度,最好返回到其他字符串格式设置过程。
还定义了类似的函数,这些函数被命名为 ,这些函数将返回一个 .to_wstring
std::wstring
评论
std::to_string
浮点类型的精度会降低很多。例如,返回字符串 23.432390。这使得使用这些函数无法往返浮点值。double f = 23.4323897462387526; std::string f_str = std::to_string(f);
sprintf(buf, fmt, val)
生成,格式说明符分别为”%d“、”%u“、”%ld“、”%lu“、”%lld“、”%llu“、”%f“、”%f“或”%Lf“,其中 buf
指定足够大小的内部字符缓冲区。我看了一下 printf 的 C99 标准,我认为小数位数取决于 float.h 中。#define DECIMAL_DIG
在 C++17 中,标头 charconv 中引入了新函数 std::to_chars 和 std::from_chars。
std::to_chars 与语言环境无关,不可分配, 和不投掷。
只有一小部分格式设置策略被 提供了其他库(例如 std::sprintf)。
从 std::to_chars,std::from_chars 也是如此。
std::from_chars 可以恢复的保证 格式化的每个浮点值 通过to_chars 仅当两者都提供时 函数来自同一实现
// 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\n", 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);
}
虽然它没有被编译器完全实现,但它肯定会被实现。
#include <iostream>
#include <string.h>
using namespace std;
int main() {
string s="000101";
cout<<s<<"\n";
int a = stoi(s);
cout<<a<<"\n";
s=to_string(a);
s+='1';
cout<<s;
return 0;
}
输出:
- 000101
- 101
- 1011
评论
to_string
如果您仍然将其设计为一个单独的函数,则编写朴素和通用的代码会更容易。
string IntToStr(int n)
{
string res;
bool s=n<0;
n=abs(n);
do
res=char(n%10+48)+res;
while(n/=10);
return s ? "-"+res : res;
}
评论