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

时间:2011-03-13 14:47:31

标签: c++ string type-conversion numeric c++-faq

由于每周都会询问此问题,因此FAQ可能会帮助很多用户。

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

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

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

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

5 个答案:

答案 0 :(得分:122)

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不是0,则idx将包含未用于解码的第一个字符的索引。这可能是最后一个角色背后的索引。

最后,积分类型允许指定基数,对于大于9的数字,假定字母表(a=10直到z=35)。您可以在floating-point numberssigned integersunsigned integers找到有关可在此处解析的确切格式的详细信息。

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

答案 1 :(得分:84)

如何在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" 
    

    您可以使用流操作符,例如std::endlstd::hex和函数std::setw()std::setprecision()等字符串流,其方式与{{1 }}

    请勿将 coutstd::ostringstream混淆。后者已被弃用

  3. 使用boost lexical cast。如果您不熟悉boost,最好从像lexical_cast这样的小型库开始。下载并安装boost及其文档go here。尽管boost不在C ++标准中,但许多boost程序库最终都会标准化,并且boost被广泛认为是最好的C ++库。

    Lexical cast使用下面的流,所以基本上这个选项与前一个选项相同,只是更简洁。

    std::ostrstream
  4. 如何将字符串转换为C ++ 03中的数字

    1. 从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" } (对于整数(按字母顺序到整数))和atoi(对于浮点值(按字母顺序到浮点数)) 。这些函数将C样式的字符串作为参数(atof),因此它们的用法 可能 被认为是不太完美的C ++实践。 cplusplus.com提供了有关atoiatof的易于理解的文档,包括在输入错误时它们的行为方式。但是,如果输入数字太大而无法适应目标类型,则链接包含错误,根据标准,行为未定义。

      const char *
    2. 使用字符串流(这次输入字符串流,#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一样使用。同样,请勿将cinistringstream混淆。后者已被弃用。

      istrstream
    3. 使用boost lexical cast

      #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 } 会抛出lexical_cast

      类型的例外

答案 2 :(得分:2)

在C ++ 17中,标题std::to_chars中引入了新函数std::from_charscharconv

  

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

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

答案 3 :(得分:0)

我从StackOverflow的某个地方偷走了这个convienent类,将任何可流式转换为字符串:

// 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的版本。

答案 4 :(得分:-1)

#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