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

Arm*_*yan 120 c++ string numeric c++-faq type-conversion

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

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

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

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

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

Kil*_*nDS 125

更新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);
Run Code Online (Sandbox Code Playgroud)

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

如果转换成功idx且未成功0,idx则将包含未用于解码的第一个字符的索引.这可能是最后一个角色背后的索引.

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

最后,对于每个函数,还有一个重载接受a 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);
Run Code Online (Sandbox Code Playgroud)

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

如注释中所述,这些函数可以回退到默认的尾数精度,该精度可能不是最大精度.如果您的应用程序需要更高的精度,最好还是回到其他字符串格式化过程.

还有一些已命名的类似函数to_wstring,这些函数将返回一个std::wstring.

  • `std :: to_string`对浮点类型失去了很多精度.例如`double f = 23.4323897462387526; std :: string f_str = std :: to_string(f);`返回一个23.432390的字符串.这使得使用这些函数无法往返浮点值. (3认同)
  • 所有这些函数都受全局语言环境的影响,如果使用库,可能会导致问题,尤其是在使用线程时.请在此处查看我的问题:http://stackoverflow.com/questions/31977457/efficiently-reading-two-comma-seperated-floats-in-brackets-from-a-string-without (2认同)

Arm*_*yan 85

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

  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"  
    }
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,您也可以使用字符串流将浮点数转换为字符串,也可以根据需要格式化字符串,就像使用 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" 
    
    Run Code Online (Sandbox Code Playgroud)

    您可以使用流操纵等std::endl,std::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"
    }
    
    Run Code Online (Sandbox Code Playgroud)

如何在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*
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用字符串流(这次是输入字符串流istringstream).同样,istringstream就像使用一样cin.再次,不要混淆istringstream使用istrstream.后者已被弃用.

    #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  
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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
    }       
    
    Run Code Online (Sandbox Code Playgroud)

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

  • `atoi`的cplusplus文档不是很好,不正确.它没有提到如果字符串的数值不能在`int`中表示,那么行为是未定义的.它反过来说超出范围的值被钳制到`INT_MAX` /`INT_MIN`,这是我在C++ 03或C89中找不到的.对于不受信任/未经验证的输入,或者当处理流不支持的基础时,您需要`strtol`,它定义了错误行为.以及对"atof"/"strtod"的类似评论. (4认同)
  • 可能想添加`std :: to_string` (4认同)
  • cplusplus.com错误的"atoi".它说的是返回值"如果无法执行有效转换,则返回零值.如果正确的值超出可表示值的范围,则返回INT_MAX或INT_MIN."但规范说"如果结果的价值无法表示,行为未定." 并且"除了出错的行为,它们相当于`(int)strtol(nptr,(char**)NULL,10)`.atoi [...]函数返回转换后的值." 众所周知,cplusplus.com对初学者来说是一个令人难以置信的糟糕信息来源. (2认同)