一,C语言的字符串

在C语言里,对字符串的处理一项都是一件比较痛苦的事情,因为通常在实现字符串的操作的时候都会用到最不容易驾驭的类型——指针。

比如下面这个例子:

//example 1:

char str[12] = "Hello";

char *p = str;

*p = ''h'';  //改变第一个字母

//example 2:

char *ptr = "Hello";

*ptr = ''h'';  //错误

第一个字符串时用数组开辟的,它是可以改变的变量。而第二个字符串则是一个常量,也就是字面值。ptr只是指向它的指针而已,而不能改变指向的内容。

看两者的汇编即可明了:

char p[] = "Hello";
004114B8  mov         eax,dword ptr [string "Hello" (4166FCh)]
004114BD  mov         dword ptr [ebp-10h],eax
004114C0  mov         cx,word ptr ds:[416700h]
004114C7  mov         word ptr [ebp-0Ch],cx

char *ptr = "Hello";
004114CB  mov         dword ptr [ebp-1Ch],offset string "Hello" (4166FCh)

可见用数组和用指针是完全不相同的。

要想通过指针来改变常量是错误,正确的写法应该是用const指针。

const char *ptr = "Hello";

二,初识string类

正是因为C风格字符串(以空字符结尾的字符数组)太过复杂难于掌握,不适合大程序的开发,所以C++标准库定义了一种string类,定义在头文件<string>。注意<string.h>和<cstring>都是错误的,这两个头文件主要定义C风格字符串操作的一些方法,譬如strlen(), strcpy()等。第一个是C的头文件格式,而第二个是C++风格的头文件,但是和<string.h>是一样的,它的目的是为了和C兼容。

看下面例子:

//example 3:

string str("world");   //可以用C风格字符串初始化

string words = "Hello";

string greet = words;

string  join = greet + words;  //可以像基本类型一样操作

但是如果试图把string类型的对象直接赋给C风格的字符串的话,编译器会报错的。

string var = "Olympic";

char *ptr = var;  //error!

但是实际应用中这个问题也难以避免,很多时候我们还是需要将string类型的转化为char*来实现自定义的操作,C++标准库也为了和之前用C写的程序兼容,于是可以用string的c_str()函数。

string var = "Olympic";

char *ptr = var.c_str(); //还不能被编译

或者通过const_cast去掉其const属性亦可

char *ptr=const_cast<char *>(var.c_str()); //correct!

这样就可以通过ptr修改其指向的地址空间内容

但是c_str()为了防止意外地修改string对象,返回的是const指针,所以上面这段代码是不能被编译的。正确的应该是用const指针。

string var = "Olympic";

const char *p = var.c_str(); //Correct!

这个c_str()方法在C++IO流操作上也被广泛应用。

在打开文件时,如果要指定文件名,可以用C风格的字符串。如果用到string类型的字符串作为文件名时,就必须调用c_str()方法将其转换为一个C风格字符串。

//example 4:

string   filename;  //定义文件名称

cin >> filename;

ifstream.open(filename.c_str());  //要使用C风格字符串

三, 深入了解string类

对string有一定了解以后,我们可以来了解C++标准库定义的一系列丰富的字符串操作,当然都是基于string类型。从某一种程度上来说,string就是一种字符容器。

标准库为string定义了很多方法,包括构造、插入(insert)、替换(assign和replace)、比较(compare)、查找(find)、删除(erase)、连接(append)以及对子串的操作(substr)。而每一种操作都有很多种重载。

比如插入,除了包括标准容器的插入方式以外,string类本身还有一些特有的插入方法。

//example 5:

//与标准容器相同的插入操作:

str.insert(iter, value) //在迭代器iter之前插入value, 返回新元素的迭代器

str.insert(iter, n, value); //在迭代器iter之前插入n个value,返回void

str.insert(iter, begin, end); //在迭代器iter之前插入迭代器begin和end标记范围内的元素,返回void

//string类特有的插入方法:

str.insert(pos, n, ch); //在下标为pos的字符之前插入n个字符ch

str.insert(pos, str2); //在下标为pos的字符之前插入string类型的对象str2的副本

str.insert(pos1, str2, pos2, len); //在下标为pos1的z字符之前插入string类型str2中从下表为pos2开始的len个字符

str.insert(pos, cp); //在下标为pos的字符前插入字符指针cp指向的C风格字符串的副本

总之string是一种非常灵活的字符串类型,标准库让我们可以忽略内存管理和具体实现方式,我们只需要关注其接口就好。并且初学者在使用字符串的时候也应尽量使用这种类型,而不是C风格的字符串。

当然,无C语言学习经历的人可以例外。

深入剖析C++中的string类相关推荐

  1. 剖析java中的String之__拼接

    剖析java中的String之__拼接 分类: java 2011-08-24 17:46 31人阅读 评论(0) 收藏 举报 出处, http://blog.csdn.net/izard999/ar ...

  2. 为什么jdk中把String类设计成final

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 为什么j ...

  3. Java中的String类占用多大的内存

    写在前面 对于Java中的String类占用多大的内存空间这个问题,是最近面试中问的比较多的一个问题.很多小伙伴的回答的都不是很正确,有说不占空间的,有说1个字节的,有说2个字节的,有说3个字节的,有 ...

  4. C++中的string类用法简介

    本文主要介绍C++中的string类的常见用法. 1. 概述 string是C++标准库的一个重要的部分,主要用于字符串处理.可以使用输入输出流方式直接进行string操作,也可以通过文件等手段进行s ...

  5. c 语言string类用法,C++中的string类用法简介

    本文主要介绍C++中的string类的常见用法. 1. 概述 string是C++标准库的一个重要的部分,主要用于字符串处理.可以使用输入输出流方式直接进行string操作,也可以通过文件等手段进行s ...

  6. 标准C++中的string类的用法总结

    相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯 ...

  7. java中String类是什么_Java中的String类

    /* String类用于描述字符串事物的 那么它就提供了多个方法对字符串进行操作 方法都会用,字符串这块就结束了 常见的操作有哪些? "abcd" 它应该具备什么功能,我们才能更好 ...

  8. string类有可以调换方向的函数吗_C++中的string类的用法小结

    相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯 ...

  9. 标准C++中的string类的用法总结(转)

    http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html 相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的 ...

最新文章

  1. php读取cookie文件,PHP读取CURL模拟登录时生成Cookie文件的方法,_PHP教程
  2. vmware tools安装程序无法继续,Microsoft Runtime DLL安装程序未能完成安装。的解决方法
  3. PLSQL的截取函数
  4. 【c#】关于c#中data控件的简单用法介绍
  5. Linux中利用RAW SOCKET直接通过网卡收发数据
  6. esxi虚拟化集群_ProxmoxVE 之集群安装(V5.2)
  7. 理解关联容器“map”的关键点
  8. 永远年轻,永远热泪盈眶----致所有奋斗的ACMer
  9. metinfo mysql 数据表_《MetInfo网站管理系统》常见问题整理
  10. 深入理解Java 容器
  11. butterknife 不能绑定错误
  12. jetson nano 相关设置(开机自动登录、取消休眠和屏保、开机自启动程序)
  13. Linux 远程连接工具 【vnc viewer】 图形界面
  14. 【React Native开发】React Native控件之RefreshControl组件具体解释(21)
  15. 版本管理工具git的使用总结
  16. VS2015卸载。非常干净-亲测有用
  17. 汽车CAN通信基础知识-CAN数据结构
  18. 数学建模之层次分析法(含MATLAB代码)
  19. 制作QQ背景音乐链接
  20. Addressable资源热更新疑问

热门文章

  1. 【转】VS工具:实时可视化树
  2. 在 VS 类库项目中 Add Service References 和 Add Web References 的区别
  3. 一步步编写操作系统4 安装x86虚拟机 bochs
  4. 解决Qt graphis-view框架中,上层图元接收hover事件导致底层图元接收不到的问题
  5. 【HDU - 5091】Beam Cannon(线段树,扫描线)
  6. php继承和重载区别,php继承中方法重载(覆盖)的应用场合
  7. C# linq Expression left join如何使用
  8. php 堵塞 消息队列,PHP的并发处理
  9. 调用SMS腾讯云短信验证码API的几个坑,及详细使用流程
  10. 服务器pg信号指的是什么信号,关于atx电源PG信号检测和分析