【问题标题】:How do I convert a double into a string in C++?如何在 C++ 中将双精度数转换为字符串?
【发布时间】:2010-09-24 19:56:14
【问题描述】:

我需要将双精度值存储为字符串。我知道如果我想显示它可以使用printf,但我只想将它存储在一个字符串变量中,以便以后可以将它存储在地图中(作为,而不是)。

【问题讨论】:

  • 回答您的问题的问题:为什么要将双精度值存储在字符串中以将其存储在地图中?你打算使用字符串化的双精度作为键吗?如果没有,为什么不保持原样?
  • 有趣的地方。然而,使用双精度作为映射键可能充满危险,因为浮点值的精确比较总是如此。对字符串表示的索引可以避免这个问题。
  • 为什么要转换它?将其作为双精度存储在地图中,并避免相互转换。
  • 这听起来仍然像是在呼吁对象。工会会起作用。每个对象都向其中插入各种值,并让它自我验证。
  • 我在一个文件中只有一堆名称/值对。它不需要对象。

标签: c++ string double


【解决方案1】:

看看sprintf() 和家人。

【讨论】:

  • 我提到 printf 是因为谷歌搜索出现了一堆文章,说要使用 printf 从双精度转换为字符串。他们假设您唯一可以做的就是打印,在我的情况下这是错误的。
  • 你为什么投-1?我认为 sprintf 很好。 @BilltheLizard,sprint 将某些内容打印到 char * 而不是屏幕上。有人回答了 c 方法仍然得到了很多投票。
【解决方案2】:

您也可以使用stringstream

【讨论】:

    【解决方案3】:
    // The C way:
    char buffer[32];
    snprintf(buffer, sizeof(buffer), "%g", myDoubleVar);
    
    // The C++03 way:
    std::ostringstream sstream;
    sstream << myDoubleVar;
    std::string varAsString = sstream.str();
    
    // The C++11 way:
    std::string varAsString = std::to_string(myDoubleVar);
    
    // The boost way:
    std::string varAsString = boost::lexical_cast<std::string>(myDoubleVar);
    

    【讨论】:

    • 赞成 C++ 11 方式。我是 C++ 新手,并没有意识到有一个 to_string 函数。我正在使用 Microsoft Visual C++ 2013。
    【解决方案4】:

    如果您使用 C++,请避免使用 sprintf。它不是 C++y 并且有几个问题。字符串流是首选方法,最好封装为Boost.LexicalCast,这可以很容易地完成:

    template <typename T>
    std::string to_string(T const& value) {
        stringstream sstr;
        sstr << value;
        return sstr.str();
    }
    

    用法:

    string s = to_string(42.5);
    

    【讨论】:

      【解决方案5】:

      嘿,我刚写了这个(与这个问题无关):

      string temp = "";
      stringstream outStream;
      double ratio = (currentImage->width*1.0f)/currentImage->height;
      outStream << " R: " << ratio;
      temp = outStream.str();
      
      /* rest of the code */
      

      【讨论】:

        【解决方案6】:

        sprintf 没问题,但在 C++ 中,更好、更安全且速度稍慢的转换方法是使用stringstream

        #include <sstream>
        #include <string>
        
        // In some function:
        double d = 453.23;
        std::ostringstream os;
        os << d;
        std::string str = os.str();
        

        你也可以使用Boost.LexicalCast:

        #include <boost/lexical_cast.hpp>
        #include <string>
        
        // In some function:
        double d = 453.23;
        std::string str = boost::lexical_cast<string>(d);
        

        在这两种情况下,str 之后应该是 "453.23"。 LexicalCast 有一些优点,它可以确保转换是完整的。它在内部使用stringstreams。

        【讨论】:

          【解决方案7】:

          升压(tm)方式:

          std::string str = boost::lexical_cast<std::string>(dbl);
          

          标准 C++ 方式:

          std::ostringstream strs;
          strs << dbl;
          std::string str = strs.str();
          

          注意:不要忘记#include &lt;sstream&gt;

          【讨论】:

          • 我认为 boost::lexical_cast 几乎是标准的 C++ 方式,只是为您精心打包。顺便说一句,litb,你有一个小错字——“boot:lexical_cast”。
          • boost::lexical_cast 不仅仅是对字符串流代码的简单包装。许多转换例程都是内联实现的。根据本页底部的性能测量 (boost.org/doc/libs/1_47_0/libs/conversion/lexical_cast.htm),boost::lexical_cast 比使用 stringstreams 更快,并且在大多数情况下,比 scanf/printf 更快
          • @Ferr 谁说这是一个简单的包装器?感谢您提供链接,我实际上确实认为它或多或少是一个简单的包装器:)
          • 不要忘记 #include &lt;sstream&gt; 为 c++ 方式:)
          • 为了文档,如果你不#include &lt;sstream&gt;,你会得到一个错误“不完整的类型是不允许的。”
          【解决方案8】:

          You may want to read my prior posting on SO. (Macro'ed version with a temporary ostringstream object.)

          郑重声明:在我自己的代码中,我赞成 snprintf()。使用本地堆栈上的 char 数组,它并不是那么低效。 (好吧,也许如果你超出了数组大小并循环执行两次......)

          (我也通过 vsnprintf() 封装了它。但这需要我进行一些类型检查。如果你想要代码,请叫喊...)

          【讨论】:

            【解决方案9】:

            lexical_cast 的问题是无法定义精度。通常,如果您要将双精度数转换为字符串,那是因为您想将其打印出来。如果精度太大或太小,都会影响您的输出。

            【讨论】:

              【解决方案10】:

              标准 C++11 方式(如果你不关心输出格式):

              #include <string>
              
              auto str = std::to_string(42.5); 
              

              to_string 是在N1803 (r0)、N1982 (r1) 和N2408 (r2)“简单数字访问”中引入的新库函数。还有stod 函数可以执行反向操作。

              如果您确实想要与"%f" 不同的输出格式,请使用snprintfostringstream 方法,如其他答案所示。

              【讨论】:

              • 哦,是的,宝贝。 to_string 和 stod 都可以在 Visual Studio 11 中使用。
              • 哦,亲爱的宝贝... to_string 在 VisualStudio 2010 中似乎不起作用):那,或者我不知道我在做什么(很有可能)
              • 有没有办法让这个函数不添加比需要更多的小数?当我转换双 8.0 时,它给了我字符串 "8.000000",而 "8" 会很好。
              • 你可以做类似for(int lsd=str.len(); lsd&gt;0 &amp;&amp; str[lsd] == '0'; lsd--); str = str.substr(lsd);
              • 这不适用于小数字...例如:1e-9 产生 0.000000
              【解决方案11】:

              您可以尝试更紧凑的样式:

              std::string number_in_string;
              
              double number_in_double;
              
              std::ostringstream output;
              
              number_in_string = (dynamic_cast< std::ostringstream*>(&(output << number_in_double <<
              
              std::endl)))->str(); 
              

              【讨论】:

                【解决方案12】:

                我会查看C++ String Toolkit Libary。刚刚在其他地方发布了类似的答案。我发现它非常快速且可靠。

                #include <strtk.hpp>
                
                double pi = M_PI;
                std::string pi_as_string  = strtk::type_to_string<double>( pi );
                

                【讨论】:

                  【解决方案13】:

                  通常,您必须使用 ecvt、fcvt 或 gcvt 函数进行此操作:

                  /* gcvt example */
                  #include <stdio.h>
                  #include <stdlib.h>
                  
                  main ()
                  {
                    char buffer [20];
                    gcvt (1365.249,6,buffer);
                    puts (buffer);
                    gcvt (1365.249,3,buffer);
                    puts (buffer);
                    return 0;
                  }
                  
                  Output:
                  1365.25
                  1.37e+003   
                  

                  作为一个函数:

                  void double_to_char(double f,char * buffer){
                    gcvt(f,10,buffer);
                  }
                  

                  【讨论】:

                    【解决方案14】:

                    使用to_string()
                    示例:

                    #include <iostream>   
                    #include <string>  
                    
                    using namespace std;
                    int main ()
                    {
                        string pi = "pi is " + to_string(3.1415926);
                        cout<< "pi = "<< pi << endl;
                    
                      return 0;
                    }
                    

                    自己运行:http://ideone.com/7ejfaU
                    这些也可用:

                    string to_string (int val);
                    string to_string (long val);
                    string to_string (long long val);
                    string to_string (unsigned val);
                    string to_string (unsigned 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);
                    

                    【讨论】:

                      【解决方案15】:

                      您可以使用此功能将任何东西转换为任何东西:

                      template<class T = std::string, class U>
                      T to(U a) {
                          std::stringstream ss;
                          T ret;
                          ss << a;
                          ss >> ret;
                          return ret;
                      };
                      

                      用法:

                      std::string str = to(2.5);
                      double d = to<double>("2.5");
                      

                      【讨论】:

                        【解决方案16】:

                        你可以在 C++11 中使用std::to_string

                        double d = 3.0;
                        std::string str = std::to_string(d);
                        

                        【讨论】:

                        • 我的数字非常小,std::to_string() 只是返回 0.000000 而不是科学形式。
                        • @erfan 如何解决这个问题?
                        • @laughing 一种方法是使用std::stringstream myStringStream,然后使用myStringStream &lt;&lt; myDouble。你也可以使用std::setprecision(x)
                        • @erfan 很好,谢谢。还有比这更短的吗?
                        【解决方案17】:

                        请注意,字符串只是双精度的表示,将其转换回双精度可能不会产生相同的值。 另请注意,默认字符串转换可能会将转换修剪到一定的精度。 在标准 C++ 方式中,您可以按如下方式控制精度:

                        #include <sstream>
                        #include <math.h>
                        #include <iostream>
                        #include <iomanip>
                        
                        int main()
                        {
                            std::ostringstream sout;
                            sout << M_PI << '\n';
                            sout << std::setprecision(99) << M_PI << '\n';
                            sout << std::setprecision(3) << M_PI << '\n';
                            sout << std::fixed; //now the setprecision() value will look at the decimal part only.
                            sout << std::setprecision(3) << M_PI << '\n';
                            std::cout << sout.str();
                        }
                        

                        这会给你输出

                        3.14159                                                                                                                                                                            
                        3.141592653589793115997963468544185161590576171875                                                                                                                                 
                        3.14                                                                                                                                                                               
                        3.142  
                        

                        【讨论】:

                          猜你喜欢
                          • 2013-10-10
                          • 2015-04-10
                          • 1970-01-01
                          • 2012-07-09
                          • 2022-01-20
                          • 1970-01-01
                          • 2014-01-01
                          相关资源
                          最近更新 更多