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

发布于 2024-10-21 17:33:37 字数 258 浏览 7 评论 0原文

由于这个问题每周都会被问到,因此这个常见问题解答可能会对很多用户有所帮助。

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

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

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

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

Since this question gets asked about every week, this FAQ might 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++

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

子栖 2024-10-28 17:33:37

C++11 更新

C++11 标准开始,字符串到数字的转换(反之亦然)内置于标准库中。以下所有函数都存在于 中(根据第 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=10z=35)。您可以找到有关可在此处解析的浮点数、< a href="http://en.cppreference.com/w/cpp/string/basic_string/stol">有符号整数 和 无符号整数

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

Update for C++11

As of the C++11 standard, 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).

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_argument or std::out_of_range).

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

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

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

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.

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.

陈甜 2024-10-28 17:33:37

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

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

     #include ; //包含它以使用字符串流
     #include <字符串> 
    
    int main()
    {    
        整数=1234;
    
        std::ostringstream ostr; //输出字符串流
        奥斯特<<数字; //像cout一样使用字符串流,
        //除了流不打印到标准输出而是打印到字符串。
    
        std::string theNumberString = ostr.str(); //流的str()函数 
        //返回字符串。
    
        //现在数字字符串是“1234”  
    }
    

    请注意,您还可以使用字符串流将浮点数转换为字符串,也可以根据需要格式化字符串,就像使用 cout

    std::ostringstream ostr;
    浮点数 f = 1.2;
    整数 i = 3;
    奥斯特<< f << “+”我<< ”=“<< f + i;   
    std::string s = ostr.str();
    //现在 s 是“1.2 + 3 = 4.2” 
    

    您可以使用流操纵器,例如 std::endlstd::hex 和函数 std::setw()std::set precision() 等使用字符串流,其方式与 cout

    完全相同

    不要将 std::ostringstreamstd::ostrstream 混淆。。后者已被弃用

  3. 使用增强词法转换 。如果您不熟悉 boost,最好从像 lexical_cast 这样的小型库开始。要下载并安装 boost 及其文档,请转到此处。尽管 boost 不是 C++ 标准,但许多 boost 库最终都得到了标准化,并且 boost 被广泛认为是最好的 C++ 库。

    词法转换使用底层的流,所以基本上这个选项与前一个选项相同,只是不那么冗长。

    #include ;
    #include <字符串>
    
    int main()
    {
       浮点数 f = 1.2;
       整数我 = 42;
       std::string sf = boost::lexical_cast(f); //sf 是“1.2”
       std::string si = boost::lexical_cast(i); //sf 是“42”
    }
    

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

  1. 从 C 继承的最轻量级选项是函数 atoi (用于整数(按字母顺序到整数))和 atof (对于浮点值(按字母顺序到浮点数))。这些函数采用 C 样式字符串作为参数 (const char *),因此它们的使用可能被认为是不完全好的 C++ 实践。 cplusplus.com 上有关于 atoi 和 < a href="http://en.cppreference.com/w/cpp/string/byte/atof" rel="noreferrer">atof 包括它们在输入错误时的行为方式。然而,该链接包含一个错误,根据标准,如果输入数字太大而无法适应目标类型,则行为未定义。

    #include ; //标准C库头文件
    #include <字符串>
    int main()
    {
        std::string si = "12";
        std::string sf = "1.2";
        int i = atoi(si.c_str()); //c_str() 函数“转换” 
        双 f = atof(sf.c_str()); //std::string 到 const char*
    }
    
  2. 使用字符串流(这次输入字符串流,istringstream)。同样,istingstream 的使用方式与 cin 类似。再次强调,不要将 istringstreamistrstream 混淆。后者已被弃用。

    #include ;
    #include <字符串>
    int main()
    {
       std::string inputString = "1234 12.3 44";
       std::istringstream isstr(inputString);
       整数 i1,i2;
       浮动 f;
       isstr>> i1>> f>> i2;
       //i1为1234,f为12.3,i2为44  
    }
    
  3. 使用增强词法转换

    #include ;
    #include <字符串>
    
    int main()
    {
       std::string sf = "42.2"; 
       std::string si = "42";
       浮点 f = boost::lexical_cast(sf); //f为42.2
       int i = boost::lexical_cast(si); //我是42
    }       
    

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

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

  1. Do not use the itoa or itof functions 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::hex and functions std::setw(), std::setprecision() etc. with string streams in exactly the same manner as with cout

    Do not confuse std::ostringstream with 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"
    }
    

How to convert a string to a number in 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 may be considered a not exactly good C++ practice. cplusplus.com has easy-to-understand documentation on both atoi and atof including 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 istringstream with 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_cast throws an exception of type boost::bad_lexical_cast

朕就是辣么酷 2024-10-28 17:33:37

在 C++17 中,新函数 std::to_charsstd::from_chars 在标头 charconv

std::to_chars 与区域设置无关,非分配,
和非投掷。

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

来自 std::to_chars,与 std::from_chars

保证 std::from_chars 可以恢复
每个格式化的浮点值
仅当两者都满足时才提供 by to_chars exactly
函数来自相同的实现

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

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

In C++17, new functions std::to_chars and std::from_chars are introduced in header 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.

From std::to_chars, same for 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

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

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

栖迟 2024-10-28 17:33:37

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

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

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

And then you use it as;

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

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)

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

Use as:

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

You might also want versions for wstrings.

东北女汉子 2024-10-28 17:33:37

如果您仍然将其设计为单独的函数,则更容易编写简单且通用的代码。

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

If you still design it as a separate function, it's easier to write naive and universal code.

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;
}
冰魂雪魄 2024-10-28 17:33:37
#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
#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;
}

Output:

  • 000101
  • 101
  • 1011
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文