繁体   English   中英

如何在C++中将数字转换为字符串,反之亦然

[英]How to convert a number to string and vice versa in C++

由于这个问题每周都会被问到,这个常见问题可能会帮助很多用户。

  • 如何在C++中将整数转换为字符串

  • C++中如何将字符串转换为整数

  • C++中如何将浮点数转换为字符串

  • C++中如何将字符串转换为浮点数

C++11 更新

C++11标准开始,字符串到数字的转换和反之亦然被内置到标准库中。 <string>中包含以下所有函数(根据第 21.5 段)。

字符串转数字

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_argumentstd::out_of_range )。

如果转换成功并且idx不为0idx将包含未用于解码的第一个字符的索引。 这可能是最后一个字符后面的索引。

最后,整数类型允许指定基数,对于大于 9 的数字,假定字母表( a=10直到z=35 )。 您可以在此处找到有关可以为浮点数、有符号整数无符号整数解析的确切格式的更多信息。

最后,对于每个函数,还有一个接受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

如何在C++03中将数字转换为字符串

  1. 不要使用itoaitof函数,因为它们是非标准的,因此不可移植。
  2. 使用字符串流

     #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"

    您可以以与cout完全相同的方式对字符串流使用流操作std::setprecision() ,例如std::endlstd::hex和函数std::setw()std::setprecision()

    不要将std::ostringstreamstd::ostrstream 后者已弃用

  3. 使用boost lexical cast 如果您不熟悉 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中将字符串转换为数字

  1. 从 C 继承而来的最轻量级的选项是函数atoi (用于整数(按字母顺序到整数))和atof (用于浮点值(按字母顺序到浮点数))。 这些函数将 C 风格的字符串作为参数( const char * ),因此它们的使用可能被认为是一种不太好的 C++ 实践。 cplusplus.com 有关于atoiatof 的易于理解的文档,包括它们在输入错误时的行为方式。 然而,链接包含一个错误,根据标准,如果输入数字太大而无法适应目标类型,则行为未定义。

     #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* }
  2. 使用字符串流(这次是输入字符串流, istringstream )。 同样, istringstream 的使用就像cin一样。 同样,不要将istringstreamistrstream混淆。 后者已弃用。

     #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 }
  3. 使用boost lexical cast

     #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 }

    如果输入错误, lexical_cast会抛出boost::bad_lexical_cast类型的异常

在C ++ 17,新的功能的std :: to_chars标准:: from_chars在报头被引入的Charconv

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);
}

虽然编译器没有完全实现,但肯定会实现。

我从 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");

您可能还需要 wstrings 的版本。

#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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM