一、字符转换
在前面对字符的转换进行了很多次的说明和分析。当然,侧重点不同,所以可能导致的处理方法有所不同。见惯了这么多的解决问题的思路和方法,一般来说,在同一个层次下,解决问题的思路就是平衡,要么要速度要么要空间,要么要安全,要么各有一些。总之,能够兼而有之的,一般来说都是技术或标准的迭代,而非在既有层次上解决。
本篇会针对C++17中字符转换的方法进行总结分析,然后与其它的方法初步进行对比分析,从而能更好的理解这些字符串转换的应用场景。
二、C++17中的std::to_chars 与 std::from_chars
在前面的“初等字符串转化”中已经对这两个函数进行了基本的说明,此处不再做重复。需要提醒的是,C++库中是使用模板来实现的,但在某些库中或过渡版本中使用的是重载的版本。它们的优势非常明显:
1、高性能且适用性强,大幅减少了数据的复制
2、不抛出异常,保证转换过程的安全
3、提供了良好的错误处理机制和类型转换机制
其实不抛出异常才是重要看点,至少不会因为遇到一些特殊符号或啥原因,引起程序Crash。
下面看一些除基本应用方式外的用法:
1、std::to_chars
进制间的处理:
//进制转换
#include <charconv>
#include <iostream>
#include <system_error>
int main() {
int num = 255;
char buf[30];
//2进制
auto ret = std::to_chars(buf, buf + sizeof(buf), num, 2);//2,16,8
if (ret.ec == std::errc()) {
std::cout << "result is: " << std::string(buf, ret.ptr) << std::endl;
}
return 0;
}
在使用前需要处理一些特殊值,如下面的正负无穷和未定义数据:
#include <charconv>
#include <iostream>
#include <cmath>
#include <system_error>
int main() {
double num = std::numeric_limits<double>::infinity();
if (std::isinf(num)) {
std::cout << "infinity" << std::endl;
} else if (std::isnan(num)) {
std::cout << "NaN" << std::endl;
}
return 0;
}
2、 std::from_chars
在实际的应用场景中经常可以用来只处理部分字符串或者只专注某一段,那么在以前可能需要处理字符串然后再进行处理,而std::from_chars可以直接使用:
#include <charconv>
#include <iostream>
#include <system_error>
int main() {
const char* str = "6789Tste";
int num;
auto result = std::from_chars(str, str + 8, num);
if (result.ec == std::errc()) {
std::cout << "is ok: " << num << std::endl;
} else {
std::cerr << "err: " << static_cast<int>(result.ec) << std::endl;
}
return 0;
}
三、注意点
使用std::to_chars 与 std::from_chars两个函数时,有几个需要注意的地方:
1、要保持转换的数据的进制的一致性,比如不要把十六进制的转十进制及这种类似的情况
2、缓冲区要保证足够,否则可能会转换失败
3、要检查返回值(to_chars_result和from_chars_result)并处理相关问题
4、仍然要处理空格等问题,并密切关注由此产生的3问题
四、与其它的比较
前面刚刚分析过使用流的技巧来进行字符转换,那么包括前面提到的sscanf、sprintf、std::to_string以及stoi、stringstream等和它们的比较有什么不同呢?最主要的就两个:
1、不抛出异常
这点非常重要,谁也不想一点小问题搞得程序崩溃
2、相对易用
虽然比之stoi,std::to_string可能稍逊,但对于流等操作要简单易用许多。再加上第一条的不抛出异常,用起来就更方便了
其它的比如内存处理之类觉得都不是什么大问题,这种操作一般内存分析不会多大,即使浪费也浪费不了多少。
五、总结
简单方便是一种趋势。虽然有人诟病C++现在是个大缸,啥都往里面放。但不可否认,新标准在不断的提高着语言整体的易用性,这也给开发者们一个思路,也就是常说的“简约但不简单”。