免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 9017 | 回复: 25

std::string你也许不知道的秘密 [复制链接]

论坛徽章:
0
发表于 2011-12-29 14:53 |显示全部楼层
  1. int main(int argc, char** argv) {
  2.     char buffer[32] = {0};
  3.     buffer[0] = 0;
  4.     buffer[1] = 'E';
  5.     buffer[2] = 'L';
  6.     buffer[3] = 'L';
  7.     buffer[4] = 'O';
  8.     string s(buffer, 32);

  9.     string b = "hello";
  10.     b = s + b;
  11.     cout << "b:"<<b << endl;
  12.     cout <<"s.size():"<< s.size() << endl;
  13.     cout <<"s:"<< s << endl;
  14.     cout << "s.c_str()"<<s.c_str() << endl;

  15.     return 0;
  16. }
复制代码
结果很奇怪
b:ELLOhello
s.size():37
s:ELLO
s.c_str():

结果是s.c_str()与s打印出来完全不同

我是在写文件的时候 用fwrite 了一个string 发现写出来的东西很奇怪,才发现string和c_str的不同,蛋都疼了


论坛徽章:
0
发表于 2011-12-29 14:59 |显示全部楼层
很正常啊, c str和 c++ str,本来就不同。

论坛徽章:
0
发表于 2011-12-29 14:59 |显示全部楼层
回复 2# AD8018


    {:3_201:}
那我怎么安全的使用c_str()调用C库函数啊

论坛徽章:
0
发表于 2011-12-29 15:06 |显示全部楼层
hy036630 发表于 2011-12-29 14:59
回复 2# AD8018


保证字符串中不出现0即可。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
发表于 2011-12-29 15:17 |显示全部楼层
hy036630 发表于 2011-12-29 14:59
回复 2# AD8018


是不知道, 居然 cout << s 还能打印出 0 后面的字符, 还能把 第一个0 给忽略, 简直强大的让人莫名其妙。
std::string.data() 与 std::string.size() 相互配合, 以使用 void* 语意。
自从知道了 c_str() 实际内部使用 malloc 以保证 c_str 返回的缓冲以 0 结尾后, 我就再也不使用它了

论坛徽章:
0
发表于 2011-12-29 15:21 |显示全部楼层
本帖最后由 AD8018 于 2011-12-29 15:21 编辑
zylthinking 发表于 2011-12-29 15:17
自从知道了 c_str() 实际内部使用 malloc 以保证 c_str 返回的缓冲以 0 结尾后, 我就再也不使用它了


这个我到现在还不知道。难以置信。

论坛徽章:
0
发表于 2011-12-29 17:36 |显示全部楼层
回复 6# AD8018


   哇  string还隐藏了这么多啊  蛋疼 用得我好怕

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2011-12-29 18:08 |显示全部楼层
lz也就算了…… ls另两位是来卖萌的对吗  越说越玄乎了…… C++就那么可怕么……
其实string,cout没有什么秘密,真正的秘密是终端对非打印字符的显示方式

重定项到文件然后查看文件内容: ./executable > output.txt
或者如果LESSCHARSET设置正确的话: ./executable | less
就可以看见内容了

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
发表于 2011-12-29 18:11 |显示全部楼层
OwnWaterloo 发表于 2011-12-29 18:08
lz也就算了…… ls另两位是来卖萌的对吗  越说越玄乎了…… C++就那么可怕么……
其实string,cout没有什 ...


我是真不知道ostream 针对 string的行为, 顺便将c_str() 这个陷阱抖一抖, 因为我确信肯定有人不知道

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2011-12-29 18:15 |显示全部楼层
实际输出内容如下:

  1. b:^@ELLO^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@hello
  2. s.size():32
  3. s:^@ELLO^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
  4. s.c_str()
复制代码
^@是'\0' 。 lz的终端可能没法显示出这个字符而已。

我还奇怪的是……  lz你在1楼帖出的输出是你自己手敲的?
要是你偷点懒, 想到重定项到文件后再复制粘贴, 问题应该就解决了……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP