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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5290089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:51:07  来源:igfitidea点击:

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

c++stringtype-conversionnumericc++-faq

提问by Armen Tsirunyan

Since this question gets asked about every week, this FAQmight help a lot of users.

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

  • How to convert an integer to a string in C++

  • how to convert a string into an integer in C++

  • how to convert a floating-point number to a string in C++

  • how to convert a string to a floating-point number in C++

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

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

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

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

回答by KillianDS

Update for C++11

C++11 更新

As of the C++11standard, string-to-number conversion and vice-versa are built in into the standard library. All the following functions are present in <string>(as per paragraph 21.5).

作为C++11标准,字符串到数字的转换和反之亦然被内置到标准库中。以下所有功能都存在于<string>(根据第 21.5 段)。

string to numeric

字符串转数字

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

Each of these take a string as input and will try to convert it to a number. If no valid number could be constructed, for example because there is no numeric data or the number is out-of-range for the type, an exception is thrown (std::invalid_argumentor std::out_of_range).

每个都以字符串作为输入,并尝试将其转换为数字。如果无法构造有效数字,例如因为没有数字数据或数字超出类型的范围,则会引发异常(std::invalid_argumentstd::out_of_range)。

If conversion succeeded and idxis not 0, idxwill contain the index of the first character that was not used for decoding. This could be an index behind the last character.

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

Finally, the integral types allow to specify a base, for digits larger than 9, the alphabet is assumed (a=10until z=35). You can find more information about the exact formatting that can parsed here for floating-point numbers, signed integersand unsigned integers.

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

Finally, for each function there is also an overload that accepts a std::wstringas it's first parameter.

最后,对于每个函数,还有一个接受 astd::wstring作为第一个参数的重载。

numeric to string

数字到字符串

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

These are more straightforward, you pass the appropriate numeric type and you get a string back. For formatting options you should go back to the C++03 stringsream option and use stream manipulators, as explained in an other answer here.

这些更简单,您传递适当的数字类型并返回一个字符串。对于格式化选项,您应该回到 C++03 stringsream 选项并使用流操纵器,如此处的其他答案中所述。

As noted in the comments these functions fall back to a default mantissa precision that is likely not the maximum precision. If more precision is required for your application it's also best to go back to other string formatting procedures.

如评论中所述,这些函数回退到默认尾数精度,这可能不是最大精度。如果您的应用程序需要更高的精度,最好返回到其他字符串格式化程序。

There are also similar functions defined that are named to_wstring, these will return a std::wstring.

也定义了类似的命名函数to_wstring,这些函数将返回一个std::wstring.

回答by Armen Tsirunyan

How to convert a number to a string in C++03

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

  1. Do not usethe itoaor itoffunctions because they are non-standard and therefore not portable.
  2. Use string streams

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

    Note that you can use string streams also to convert floating-point numbers to string, and also to format the string as you wish, just like with 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" 
    

    You can use stream manipulators, such as std::endl, std::hexand functions std::setw(), std::setprecision()etc. with string streams in exactly the same manner as with cout

    Do not confusestd::ostringstreamwith std::ostrstream. The latter is deprecated

  3. Use boost lexical cast. If you are not familiar with boost, it is a good idea to start with a small library like this lexical_cast. To download and install boost and its documentation go here. Although boost isn't in C++ standard many libraries of boost get standardized eventually and boost is widely considered of the best C++ libraries.

    Lexical cast uses streams underneath, so basically this option is the same as the previous one, just less verbose.

    #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"
    }
    
  1. 不要使用itoa还是itof因为他们是非标准的,因此不便于携带的功能。
  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()等用绳子流在完全相同的方式与相同cout

    不要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"
    }
    

How to convert a string to a number in C++03

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

  1. The most lightweight option, inherited from C, is the functions atoi(for integers (alphabetical to integer)) and atof(for floating-point values (alphabetical to float)). These functions take a C-style string as an argument (const char *) and therefore their usage maybe considered a not exactly good C++ practice. cplusplus.com has easy-to-understand documentation on both atoiand atofincluding how they behave in case of bad input. However the link contains an error in that according to the standard if the input number is too large to fit in the target type, the behavior is undefined.

    #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. Use string streams (this time input string stream, istringstream). Again, istringstream is used just like cin. Again, do not confuse istringstreamwith istrstream. The latter is deprecated.

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

    In case of a bad input, lexical_castthrows an exception of type boost::bad_lexical_cast

  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

回答by JiaHao Xu

In C++17, new functions std::to_charsand std::from_charsare introduced in header charconv.

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

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_chars? 与语言环境无关、非分配且非抛出。

仅提供了其他库(例如?std::sprintf)使用的一小部分格式化策略。

From std::to_chars, same for std::from_chars.

std ::to_chars 开始,对于std::from_chars 也是如此

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

仅当两个函数都来自同一实现时才提供 ?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 = '
// 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_;
};
'; 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); }

Although it's not fully implemented by compilers, it definitely will be implemented.

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

回答by Viktor Sehr

I stole this convienent class from somewhere here at StackOverflow to convert anything streamable to a string:

我从 StackOverflow 的某个地方偷了这个方便的类,以将任何可流式传输的内容转换为字符串:

string str = make_string() << 6 << 8 << "hello";

And then you use it as;

然后你把它用作;

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

Quite nifty!

相当漂亮!

Also I use this function to convert strings to anything streamable, althrough its not very safe if you try to parse a string not containing a number; (and its not as clever as the last one either)

此外,我使用此函数将字符串转换为任何可流式传输的内容,但如果您尝试解析不包含数字的字符串,则它不是很安全; (而且也不如上一个聪明)

int x = parse_string<int>("78");

Use as:

用于:

##代码##

You might also want versions for wstrings.

您可能还需要 wstrings 的版本。