C++字符串与数值的转换

字符串转换

C风格字符串


简单转换函数

#include <stdlib.h>
int atoi(const char *str);
long atoi(const char *str);
long long atoll(const char *str);   //(c99)

以上三个函数将str所指向的字符串转化为整数。转化过程会忽略所有的前置空白符,直到找到首个非空白符,然后尽可能多的接受包含以下部分的合法整数:

  • (可选的)正负号
  • 数字

转化成功时,函数返回字符串对应的整数值;若无法进行转换,则返回0;如果转换结果超出了返回类型的范围,则返回值未定义。


指定进制的转换函数

#include <stdlib.h>
long                strtol(const char *str, char **str_end,
                            int base);
unsigned long       strtoul(const char *str, char **str_end,
                            int base);
long long           strtoll(const char *str, char **str_end,
                            int base);  //(c99)
unsigned long long  strtoull(const char *str, char **str_end,
                            int base);  //(c99)

#include <inttypes.h>
intmax_t strtoimax(const char *str, char **str_end,
                    int base);  //(c99)
uintmax_t strtoumax(const char *str, char **str_end,
                    int base);  //(c99)

以上六个函数将str所指向的字符串转化为整数。转化过程会忽略所有的前置空白符,直到找到首个非空白符,然后取尽可能多的字符组成base进制的整数,合法的整数包含以下部分:

  • (可选的)正负号
  • (可选的)8进制前缀(0)。
  • (可选的)16进制前缀(0x或0X)。
  • 数字。

参数base用于指定进制。可能取值为0到36之间的整数。如果base为0,则函数自动检测进制数,如果前缀为0,则为8进制;如果前缀为0x,则为16进制;否则为10进制。

参数str_end用于返回最后一个被转换字符的后一个字符的地址。如果传入空指针,则忽略它。

函数调用成功后返回字符串对应的整数值;若无法进行转换,则返回0;如果转换结果超出了返回类型的范围,则返回LONG_MAX、LONG_MIN、ULONG_MAX、LLONG_MAX、LLONG_MIN、ULONG_LONG_MAX、INTMAX_MAX、INTMAX_MIN、UINTMAX_MAX、0中最接近的值,并设置errno(ERANGE)。


浮点数转换函数

#include <stdlib.h>
double atof(const char *str);

该函数将str所指向的字符串转化为双精度浮点数。转化过程会忽略所有的前置空白符,直到找到首个非空白符,然后取尽可能多的字符组成浮点数,合法的浮点数可以是以下形式之一:

  • 十进制浮点数,由以下部分组成:
    • (可选的)正负号
    • 非空的十进制数字序列,可以包含一个可选的小数点。
    • (可选的)e或E,后跟一个合法整数。
  • 二进制浮点数,由以下部分组成:
    • (可选的)正负号
    • 0x或0X
    • 非空的十六进制数字序列,可以包含一个可选的小数点。
    • (可选的)p或P,后跟一个合法整数(以2为指数的底数)。
  • 无穷大,由以下部分组成:
    • (可选的)正负号
    • INF或INFINITY,不区分大小写
  • NaN,由以下部分组成:
    • (可选的)正负号
    • NAN或NAN(char sequence),不区分NAN部分的大小写。char_sequence只能由数字、拉丁字母和下划线构成,返回值是一个QNAN(Quiet NAN)。

函数调用成功后返回字符串对应的浮点数值;若无法进行转换,则返回0.0;如果转换结果超出了返回类型的范围,则返回值未定义。

#include <stdlib.h>
float strtof(const char *str, char **str_end);          //(c99)
double strtod(const char *str, char **str_end);
long double strtold(const char *str, char **str_end);   //(c99)

以上三个函数用于将str所指向的字符串转化为浮点数。str部分的描述与atof一致,整体用法与指定进制的整数转换函数类似,只是无法显式指定进制。不做过多解释。


数值转换为字符串

C标准库中没有专门提供数值转换为字符串的函数,但可以使用格式化输出(sprintf和snprintf(c11))将数值输出到缓冲区中。


C++风格字符串


整数转换

#include <string>
int                 stoi(const std::string &str,
                            std::size_t *pos = 0,
                            int base = 10);   //(c++11)
long                stol(const std::string &str,
                            std::size_t *pos = 0,
                            int base = 10);   //(c++11)
long long           stoll(const std::string &str,
                            std::size_t *pos = 0,
                            int base = 10);   //(c++11)
unsigned long       stoul(const std::string &str,
                            std::size_t *pos = 0,
                            int base = 10);   //(c++11)
unsigned long long  stoull(const std::string &str,
                            std::size_t *pos = 0,
                            int base = 10);   //(c++11)

以上函数将字符串str转化为整数。
参数pos用于返回str中参与转化的字符数。
参数base用于指定进制。

以上函数一般使用strto函数族实现,对于字符串的格式要求也与strto函数族要求一样。这里不再赘述。

转化成功时,函数返回字符串对应的整数值;若无法进行转换,则抛出std::invalid_argument异常;如果转换结果超出了返回类型的范围,或底层strto函数设置error(ERANGE)则抛出std::out_of_range异常。


浮点数转换

#include <string>
float       stof(const std::string &str,
                    std::size_t *pos = 0);    //(c++11)
double      stod(const std::string &str,
                    std::size_t *pos = 0);    //(c++11)
long double stold(const std::string &str,
                    std::size_t *pos = 0);    //(c++11)

以上函数将字符串str转化为浮点数。
使用方法与stoi等函数一致,对于字符串的格式要求也与strtof函数族要求一样。这里不再赘述。

转化成功时,函数返回字符串对应的浮点数值;若无法进行转换,则抛出std::invalid_argument异常;如果转换结果超出了返回类型的范围,或底层strto函数设置error(ERANGE)则抛出std::out_of_range异常。


数值转换为字符串

#include <string>
std::string to_string(int value);                   //(c++11)
std::string to_string(long value);                  //(c++11)
std::string to_string(long long value);             //(c++11)
std::string to_string(unsigned value);              //(c++11)
std::string to_string(unsigned long value);         //(c++11)
std::string to_string(unsigned long long value);    //(c++11)
std::string to_string(float value);                 //(c++11)
std::string to_string(double value);                //(c++11)
std::string to_string(long double value);           //(c++11)

以上函数将数值转换为十进制字符串。参数value指定参数的值,返回值为转换后的字符串。当std::string构造异常时会抛出std::bad_alloc。


charconv

C++17提供了一组高性能,不抛出,不依赖本地环境的转换函数。在高吞吐量的环境下有良好的表现。


std::from_chars

#include <charconv>
struct from_chars_result {
    const char *ptr;
    std::errc ec;
};

enum class chars_format {
    scientific = /*unspecified*/,
    fixed = /*unspecified*/,
    hex = /*unspecified*/,
    general = fixed | scientific
};

std::from_chars_result from_chars(const char *frist,
    const char *last, /* integer */ &value, int base = 10);//c++17
std::from_chars_result from_chars(const char *frist,
    const char *last, /* floating */ &value,
    std::char_format fmt = std::chars_format::general); //c++17

参数first指向要转换字符缓冲区的开头,参数last指向要转换字符缓冲区的结尾。value用于返回转换的结果,参数base指定转换的进制必须介于2与36之间。

  1. 对整数分析是,只识别正负号和数字。
  2. 对浮点数分析时:
    • 不识别指数外的正号
    • 若 fmt 设置了 std::chars_format::scientific 而没有设置std::chars_format::fixed ,则要求指数部分(否则可选)
    • 若 fmt 设置了 std::chars_format::fixed 而没有设置std::chars_format::scientific ,则不允许可选的指数部分
    • 若 fmt 为 std::chars_format::hex ,则不允许前缀 "0x" 或 "0X" (字符串"0x123"分析为值 "0")。

函数调用成功后,返回一个std::from_chars_result结构体,ptr字段指向首个不匹配的字符,如果所有字符都匹配,则ptr=last,ec={}。
如果无匹配模式。则ptr=first,ec=std::errc::invalid_argument,不修改value的值。
如果如果转换结果超出了value类型的范围,则ec=std::errc::result_out_of_range,不修改value。


std::to_chars

#include <charconv>
struct to_chars_result {
    char *ptr;
    std::errc ec;
};

std::to_chars_result to_chars(chat *first, char *last,
    bool value, int base = 10) = delete;
std::to_chars_result to_chars(chat *first, char *last,
    /* integer */ value, int base = 10);            //c++17
std::to_chars_result to_chars(chat *first, char *last,
    /* floating */ value);                          //c++17
std::to_chars_result to_chars(chat *first, char *last,
    /* floating */ value, std::char_format fmt);    //c++17
std::to_chars_result to_chars(chat *first, char *last,
    /* floating */ value, std::char_format fmt,
    int precision);                                 //c++17

参数[first, last)指定输出缓冲区,value为要转换的数值。

  1. 当value为整数类型时,value被转换为base进制的字符串存储在[first, last)指定输出缓冲区中。
  2. 当value为浮点数类型时,value被转换为字符串存储在[first, last)指定输出缓冲区中。
  3. 当fmt为std::chars_format::fixed则如同对应printf的转换指定为f若fmt为std::chars_format::scientific则为e若fmt为std::chars_format::hex则为a(但结果无前导"0x"),且若fmt为chars_format::general则为g。
  4. 参数percision指定浮点数的精度。

函数调用成功后,返回一个std::to_chars_result结构体,ptr字段指向最后一个被写入字符的后一位,ec={}。
如果发生错误,ec=std::errc::value_too_large,ptr=last,[first, last)中的状态未定义。

posted @ 2020-11-28 21:37  Sigmun  阅读(1088)  评论(0)    收藏  举报