ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++ string_view 的坑(转)

2021-06-30 14:31:45  阅读:122  来源: 互联网

标签:src string C++ 字符串 post data 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

标签:src,string,C++,字符串,post,data,view
来源: https://www.cnblogs.com/xihong2014/p/14954296.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有