C++ string_view 的坑(转)
2021/6/30 14:50:42
本文主要是介绍C++ string_view 的坑(转),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
C++17引入了string_view, 这可是C++程序猿在处理字符串操作的一大福音。因为string_view基本没有涉及内存的额外分配。
但是在使用的时候,有个地方需要特别注意. 我今天就踩到了这个坑, 特此记录一下. 问题是这样的, 我写了一个函数, 入参是一个以一个点"."为分隔符的字符串. 函数的功能是把字符串的后缀(也就是点后面的部分)替换掉生成一个新的字符串.
代码如下:
1 string replace_post(string_view src, string_view new_post) 2 { 3 // 找到点的位置 4 auto pos = src.find(".") + 1; 5 // 取出点及点之前的全部字符,string_view的substr会返回一个 6 // string_view对象,所以要取data()赋值给string对象 7 string s1 = src.substr(0, pos).data(); 8 9 // 加上新的后缀 10 return s1 + new_post.data(); 11 } 12 13 14 int main() 15 { 16 string_view sv = "abcdefg.xxx"; 17 string s = replace_post(sv, "yyy"); 18 19 cout << sv << " replaced post by yyy result is:" << s << endl; 20 return 0; 21 }
这段代码导致我的程序出意料之外的bug, 所以把它记录在这里.
原本希望的结果是abcdefg.yyy, 而实际结果确是 abcdefg.xxxyyy
src.substr(0, pos).data() 得到的是原始的字符串, 这与预期明显不符啊. 难道string_view的substr方法有bug?刚开始我怀疑是编译器的bug,于是我换不同的编译器进行验证。 用vc2019, gcc9.1, gcc9.3分别做了验证, 结果都是一样的.看来C++标准就是这么定义的了. 那么substr得到是什么,c++文档里说的一个string_view对象,这个对象里到底有什么数据?
1 string replace_post(string_view src, string_view new_post) 2 { 3 // 找到点的位置 4 auto pos = src.find(".") + 1; 5 // 取出点及点之前的全部字符,string_view的substr会返回一个string_view对象,所以要取data()赋值给string对象 6 string_view sv1 = src.substr(0, pos); 7 string s1 = sv1.data(); 8 cout << "sv1 = " << sv1 << ", s1=" << s1 << endl; 9 10 // 加上新的后缀 11 return s1 + new_post.data(); 12 } 13 14 15 int main() 16 { 17 string_view sv = "abcdefg.xxx"; 18 string s = replace_post(sv, "yyy"); 19 20 cout << sv << " replaced post by yyy result is:" << s << endl; 21 return 0; 22 }
结果如下:
看来, sv1的输出是正确的. 但是sv1.data()得到确是整个原始字符串, 由此可以推断string_view内部只是简单地封装原始字符串的起始位置和结束位置, 相当于给字符串设置了一个观察窗口,用户只能看到通过窗口能看到的那部分数据. data()成员返回的是char*的指针, 是string_view内部字符串的起始位置. 所以其表现再来的行为跟C字符串一样了, 直到遇到空字符串才结束.
总结,string_view只是某个字符串上建立的一个视图. 它并不真正持有任何数据,展示给你的不一定是整个字符串,可能只是其中一部分.
但要使用string_view看到的数据又只能通过data(), 从上面例的结果来看: sv1.data() 得到的结果却不是sv1展示出来的数据, 这不是很矛盾吗?
https://www.cnblogs.com/pzhfei/p/12655601.html
这篇关于C++ string_view 的坑(转)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-06有没有什么开源的py项目可以对图像进行分类-icode9专业技术文章分享
- 2024-07-05feign默认connecttimeout和readtimeout是多少-icode9专业技术文章分享
- 2024-07-05idea控制台,日志太多,导致部分想看得日志被刷走 搜不到-icode9专业技术文章分享
- 2024-07-05The server selected protocol version Tls10 is not accepted by client preferences [TLs12]-icode9专业技术文章分享
- 2024-07-05怎么清理项目缓存-icode9专业技术文章分享
- 2024-07-04安装 Eyoucms详细图文教程-icode9专业技术文章分享
- 2024-07-04ueditor 复制文章时,图片的链接是一个下载图片地址,该如何处理?-icode9专业技术文章分享
- 2024-07-04怎样判断host有没有对wordpress有缓存呢-icode9专业技术文章分享
- 2024-07-04具有编译功能的系统make后,无法ssh连接-icode9专业技术文章分享
- 2024-07-04make后如何升级ssh-icode9专业技术文章分享