【C++】字符串详解_c++字符串-程序员宅基地

技术标签: C++  cpp  字符串  

字符串简介:
字符串是存储在内存中连续字节的一系列字符。C++中处理字符串有两种风格,一种来自C语言,叫做C语言风格;另一种风格基于string库,我们姑且叫string库风格。其中C语言风格,利用了字符串储存在内存中连续字节的特点,将字符串储存在字符数组中,以‘\0’结尾;而string库风格提供的方法,允许程序员将字符串作为变量来使用,接下来将分别介绍这两种风格。

1.C语言风格
(1)字符串和字符数组
C语言风格的处理方式是将字符串置于字符数组中,每个字符位于一个数组元素之中,并且以空字符(’\0’)结尾。以空字符结尾对C语言风格的字符串来说非常重要,这是区别字符串和字符数组的标志,比如:

char a[5] = {
    '1','2','3','4','5'};   //这是一个字符数组
char b[5] = {
    '1','2','3','4','\0'};  //这是一个字符串 

同时,字符串结尾的空字符也是很多函数判断是否到达字符串结尾的标志,如果将字符串中的某个元素设置为’\0’,那么很多函数会错误的判断字符串的结尾位置并带来错误,比如:

char dog[6] = {
    'T','e','d','d','y','\0'}; //定义一个字符串Teddy 
 cout<<"改变前: "<<dog<<"\n";             //cout会输出直到遇到末尾的空字符为止 
 dog[2] = '\0';                            //将字符'd'改为空字符 
 cout<<"改变后: "<<dog;

这样一个代码段执行结束以后的结果将是:
在这里插入图片描述
如果用户不将字符数组结尾设置为空字符,cout函数将继续将内存后面的内容解释为要打印的元素直到遇到空字符为止,但是由于空字符在内存中很常见,所以输出也将很快停止,这大多不会影响输出,但是用户仍然不应该将非空字符结尾的字符串当作字符串使用。
(2)字符串的初始化
字符串的初始化可以刚刚的范例中的那样做,使用单引号分隔单个字符并在末尾加上空字符,但这样不免繁琐。更简洁的将字符数组初始化为字符串的方式是用双引号("")将内容括起。这种字符串叫做字符串常量,或者字符串字面值。用引号括起的字符串隐式包含了结尾的空字符,不需要人为添加,但应记得为其预留位置。在这样输入字符串的时候,我们可以手动设置字符数组长度,也可以让编译器自动计算空间,比如:

 char dog[6] = "Teddy"  //人为设置,预留一个空字符的位置
 char cat[] = "Persion" //编译器计算 

需要注意的是,应当为字符串分配足够大的空间,如果分配的空间存在没用完的部分,将自动被设置为空字符’\0’
(3)字符串的拼接以及对字符串中字符操作
在C语言风格中,算术运算符’+‘不会被解释为字符串的拼接,所以不能直接使用’+'拼接两个字符串。可以使用函数strcat()达到目的,但是需要使用到string库,所以放在下面进行讲解。
在明白字符串和字符数组的关系后,就可以利用数组的性质对字符串中的字符进行操作,比如实现一个单词的大小写转化:

char dog[6] = "Teddy"; 
 for (int i=0;i<6;i++){
      //如果未知长度,可以使用strlen(dog)获取
  if(dog[i]<'Z' && dog[i]>'A'){
    
   dog[i] += 32;
  }
  else{
    
   dog[i] -= 32;

(4)字符串输入
和字符数组一样,字符串可以使用cin进行输入。但是cin使用空白(空格,换行符,制表符)确定输入边界,这意味着输入的字符串中不能含有空格(一次性只能输入一个单词),这样的问题是很明显的。
但实际上,如果空格和换行符在确认边界上有同样的效果,那么是不是意味着在运行程序时也会出现同样的结果呢?比如下面的一段代码:

char name[10];
 char food[10];
 cout<<"What is your name:";
 cin>>name;
 cout<<"What is your favorite food:";
 cin>>food;
 cout<<name<<" likes "<<food;

如果使用换行符,即使用回车来分隔两个字符串,运行范例是:
在这里插入图片描述
看起来似乎没什么问题,但如果使用空格来分割呢?
在这里插入图片描述
在这种情况下,程序员尚未对输入最喜欢的食物做出反应,程序已经将其显示了出来。这是因为使用空格以后,rice被留在了输入队列中,故当程序在输入队列搜索输入结果时发现了留在其中的rice,直接读取存入字符串中,这样也就不需要用户再输入了。
首先,一次性只能输入一个单词肯定是不好的,但是istream中的类提供了一些类成员函数,可以面向行进行输入,即是说仅把换行符(按下enter)作为输入结尾标志。这样的函数有getline()和get()两种。
区别在于getline()将会读取换行符并舍弃,而get()将保留换行符在输入队列中。这两种函数的一般形式为:cin.getline(arrayName,arrayLenth)和cin.get(arrayName,arrayLenth);代表将输入放到arrayLenth长度的arrayName的数组中去。这样就能解决使用空格作为输入边界带来的一些问题了,比如:

char name[15];
 cout<<"input name:";
 cin.getline(name,15);
 cout<<name;

测试范例为:
在这里插入图片描述
可以看到此时就可以输入含有空格的字符串了!
但是我们需要注意,由于get()函数将回车留在了队列中,可能需要另一个get()来读取回车,否则会给输入带来问题,比如:

 char pets[10];
 char food[10];
 cin.get(pets,10);
 cin.get();   //抵消留在输入队列中的字符串,也可以使用getchar() 
 cin.get(food,10);
 cout<<pets<<"\n";
 cout<<food;

2.string库风格(加入cstring或者string.h)
通过添加string类扩展了C++库,现在就可以使用string类型的变量而不是字符数组储存字符串。现在可以这样定义字符串了:

string pets = "dog and cat";

(1)赋值,拼接和附加

 string first_name;
 string last_name;
 first_name = "Mercer";  //给字符串变量赋值 
 last_name = "Alex";
 cout<<last_name+" ,"+first_name; //此处的"+"解释为字符串拼接 

(2)和字符数组的联系
实际上string类定义隐藏了字符串的数组性质,实际上string和字符数组存在很多相同,也存在一些不同,下面以一个测试程序为例:

 string first_name = "Alex";  //可以用C风格字符串初始化字符串对象 
 string last_name;
 cin>>last_name;              //可以使用cin从键盘读取到string对象中
 cout<<"full_name: "<<first_name+last_name<<"\n";//可以用cout输出 
 cout<<first_name[0];         //可以使用数组表示法输出字符串中的字符 

(3)string的输入
string类可以使用cin和>>进行输入,但是和C语言风格一样,面对空格可能带来的问题。但是之前的C语言风格中,我们使用getline(),get()时,需要确定字符数组的名称和长度,但是string类隐去了数组性质,又如何输入呢?可以使用函数getline(cin,str)来进行输入,例如:

 string full_name;
 getline(cin,full_name);

(4)一些常用函数
①strcpy --将字符串复制到字符数组中
strcpy(a,b),将数组b复制到a中,会覆盖原来a中的内容;

 char a[4] = "123";
 char b[4] = "456";
 cout<<strcpy(a,b);

结果为
在这里插入图片描述
②strcat --将字符串附加到字符串末尾
strcat(a,b),将数组b附加到a末尾,同样是刚刚的例中

 char a[4] = "123";
 char b[4] = "456";
 cout<<strcat(a,b);

结果为:
在这里插入图片描述
③strlen --输出字符串长度

 char a[4] = "123";
 cout<<strlen(a);

结果为:
在这里插入图片描述
这里需要注意,字符数组长度为4,而输出的长度为3,这是因为预留的一个元素位置是为引号括起的内容隐式添加的’\0’留的,而strlen()函数遇到空字符停止,不会将其计入字符串长度,这里也侧面反应了上面我们对C语言风格字符串初始化的观点。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_46018836/article/details/105685783

智能推荐

输入框自动增加高度-程序员宅基地

文章浏览阅读240次。[code="java"] $('[item="text_pinglun"]').keyup(function(){ var id = $(this).attr("id"); var obj = document.getElementById(id); var sh = obj.scrollHeight; $(this).a("height",sh+"px"..._input框自动加高

Qt Script之qscript_qt qscriptengine导入函数-程序员宅基地

文章浏览阅读1.1k次。这是一个简单的JS命令解释器,可以在命令行输入简单的JS代码显示运行结果。 用到的一些函数 bool QScriptEngine::canEvaluate(const QString & program) const 如果程序可以被评估则返回true;代码是足够来确定它是否是语法正确的程序或者包含一个语法错误。如果程序是不完整的则返回false。这个函数典型的用法是用来实现交互式解释器。 Q_qt qscriptengine导入函数

java线程安全问题之静态成员变量、实例成员变量、局部变量_成员变量使用静态还是单例变量-程序员宅基地

文章浏览阅读2k次,点赞2次,收藏10次。(原文地址:http://blog.csdn.net/will_awoke/article/details/38044415)java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同《java并发编程实践》中所说: 写道给线程安全下定义比较困难。存在很多种定义,如:“一个类在可以被多个线程安全调用时就是线程安全的”。..._成员变量使用静态还是单例变量

ajax回调json数据遍历取出数据_怎么从回调函数的json里取值-程序员宅基地

文章浏览阅读2.3k次。JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式。同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包。·在JSON中,有两种结构:对象和数组。1.对象一个对象以“{”开始,_怎么从回调函数的json里取值

用Microwindows(Nano-X)编写中文程序_windows下编程nano环境-程序员宅基地

文章浏览阅读1.2w次。v/:* {behavior:url(#default#VML);}o/:* {behavior:url(#default#VML);}w/:* {behavior:url(#default#VML);}.shape {behavior:url(#default#VML);} Normal 0 7.8 磅 0 2 _windows下编程nano环境

Excel函数公式大全—IF函数_excel if公式-程序员宅基地

文章浏览阅读1w次,点赞5次,收藏26次。Excel函数公式大全—IF函数:本文写了 if函数的语法,if函数的使用案例,以及留下了if函数计算BMI的练习,欢迎大家阅读。_excel if公式

随便推点

从iass向pass转型_iaas一路做到pass-程序员宅基地

文章浏览阅读311次。都说活到老学到老,这个词用在it行业更加准确 ,从毕业开始学编程,数据库,到华为学算法,售前 技能,存储,数据中心,还有各种软技能,写p p t,演讲,学习各种产品对标,竞争 分析。再到华三学习网络,新网络,云计算。一路走来一路在学,可是我总感觉有点力不从心,或许是自己 每次都是各种狼吐虎咽,没有认真去消化和吸收,没有变成自己的东西。现在出门去做项目做咨询,你如果不说说paas,说说容器和微服务..._iaas一路做到pass

初始化Mariadb数据库+远程连接数据库_mariadb初始化-程序员宅基地

文章浏览阅读3.1k次,点赞3次,收藏11次。一.初始化Mariadb数据库1.安装Mariadbyum install mariadb mariadb-server2.启动Mariadbsystemctl start mariadb.service3.初始化数据库mysql_secure_installationNOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB ``SERVERS IN PRODUCTION USE! P_mariadb初始化

TensorFlow笔记-制作自己的训练集,利用卷积神经网络模型进行训练、测试_通过卷积神经网络训练模型-程序员宅基地

文章浏览阅读2.9k次,点赞2次,收藏17次。TensorFlow笔记-制作自己的训练集,利用卷积神经网络模型进行训练、测试(完整流程)https://blog.csdn.net/jyy555555/article/details/80283219在学习TensorFlow过程中,发现训练数据集(mnist)大都是直接从网上下载,直接加载到模型上。而如果我们大多时候需要用自己的图片进行训练、测试,为了解决这个问题,在网上看了很多教程,大概..._通过卷积神经网络训练模型

velocity+spring mvc+spring ioc+ibatis初试感觉(与struts+spring+ibatis比较) - 巴士飞扬-专注编程,网站,专业技术-程序员宅基地

文章浏览阅读946次。velocity+spring mvc+spring ioc+ibatis初试感觉(与struts+spring+ibatis比较)google_ad_client = "pub-8432098110340913";/* busfly_ss_内容区左上 250x250, 创建于 08-2-2 */google_ad_slot = "2731136837";google_ad_wi

《一本书读懂24种互联网思维》用户思维1_用户思维 名言-程序员宅基地

文章浏览阅读1.2k次。用户思维就是以用户的角度进行考虑。消费者参与:让用户成为设计师。常见名句:一,乔布斯:1.一定不要浪费用户时间。2.不要想当然,不要打扰和强迫用户。3.不要以为给用户提供越多的东西就越好。4.主动尝试去接触你的用户。二,谷歌:1.一切以用户为中心,其他一切纷至沓来。Focus on the user and all else will follow.2.把一..._用户思维 名言

阿里云服务器数据云盘挂载_阿里云ecs 系统盘改xfs-程序员宅基地

文章浏览阅读560次。阿里云服务器数据云盘挂载fdisk -l ,发现有一块新的磁盘 /dev/vdb 没有被格式化挂载使用。fdisk /dev/vdb #开始进行分区操作, 接着按m 查看命令帮助按n开始新加分区,再按p 创建主分区输入扇区编号,默认1,直接回车即可输入起始扇区,默认大小2048,直接回车即可输入输入分配的分区空间大小,直接回车表示分配全部可用空间完成了按p,可查看分区结果最后按w,将修改写入分区表,保存退出。cd /devls -l | grep vdb #查..._阿里云ecs 系统盘改xfs