C++_系列自学课程_第_4_课_string_《C++ Primer 第四版》
相信学习过计算机编程的人,基本应该都接触过C语言,在C语言中处理字符串大家一定多遇到过,
也都知道处理字符串非常麻烦,而在C++里面,由标准库string类提供对可变长的字符串的支持。下面
来看看string类的特性。
1、使用的先决条件
在使用标准库之前必须包含相应的头文件, 要使用string类型,就需要包含相应的头文件,如下所示:
- #include <string>
在使用iostream的时候,我们未来引用iostream里面的类,前面需要加上 std:: 来表示引用的是标准
IO库提供的功能,同样在使用string类的时候,需要加上一个表示作用域的限制修饰的说明,如下所示:
- std::string str; //定义一个string的对象str
在每一次定义的时候都要这样使用 std:: 很麻烦,C++提供了一种更方便的机制,如下:
- using std::string;
在源文件里面加上上面这一句, 在使用的时候,就可以直接使用 string来定义对象,如下所示:
- string str;
2、string类的初始化
string类提供了多种初始化方法:
1) string str; //初始化为空字符串, 调用默认构造函数,
2) string str2="volcanol"; // 赋值初始化,复制str2为"volcanol"的一个副本,
3) string str1("volcanol"); //直接初始化,调用初始化函,
4) string str1="volcanol"
string str2(str1); //利用 string对象初始化string str对象
5) string str1(3,'c'); //初始化str1为"ccc",
3、string对象的读写
可以利用iostream提供的输入和输出机制来对string对象进行操作。
输入:
- string str;
- cin>>str;
这样就可以通过标准输入来输入字符到string对象中, 要注意的是:
A) cin在输入的的时候会忽略开始的空白符(空格,制表符,换行符),然后从非空白字符开始读入
B) cin在输入的时候,会在再次遇到空白字符后结束输入。
这里的意思就是: 通过 cin>>str读入的字符流不会包含 endl 换行符,因此如果要换行的话,就
需要自己添加换行符。
同样可以利用cout<<来输出string对象,如下所示:
- cout<<str<<endl;
下面是一段例子代码:
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main(int argc,char *argv[])
- {
- string str;
- while(cin>>str)
- cout<<str<<endl;
- return ;
- }
执行情况如下所示:
- [root@localhost cpp_src]# g++ test.cpp
- [root@localhost cpp_src]# ./a.out
- a //输入a 然后按回车键
- a
- ab //输入ab,然后按下回车键
- ab
- aaa bbb ccc //输入aaa bbb ccc 按下回车键
- aaa
- bbb
- ccc
按下 ctrl+d 就会退出上面的程序, 这里while循环判断 cin>>str 是否遇到 end-of-file 结束符,
当按下ctrl+d后, cin>>str 返回 false, 结束循环。
4、getline函数的使用
通过调用 getline函数可以一次输入一行, 这里需要注意的是:getline不会忽略开始的换行符,而是会
忽略最后的换行符,而且getline在遇到 空格、制表符的时候,不会结束一行的输入,直到遇到endl换行符。
getline()接受两个参数: getline(cin, str);
Exp:
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main(int argc,char *argv[])
- {
- string str;
- while(getline(cin,str))
- cout<<str<<endl;
- return ;
- }
执行结果如下:
- [root@localhost cpp_src]# g++ test.cpp
- [root@localhost cpp_src]# ./a.out
- aaa bbb ccc ddd //输入aaa bbb ccc ddd按下换行
- aaa bbb ccc ddd
- //直接输入换行
- //直接输入换行
- //输入12345 按下换行
这里需要注意的是: getline不会忽略一行开头的换行符,而且输入后在string对象最后不会加上endl换行符。
5、string的操作
string类型提供了很多的操作, 下面我们来看一下:
string str;
str.size(); 返回str对象的长度
str.empty(); 判断str是否是空字符串
str[n]; 下标操作,取其中的一个字符
str1 + str2;
str2 =str1;
str1 == str2
还有 != , <, <=, >,>= 这些比较操作,这些操作与整数型的操作的意义一样,但是string的
比较是按照字典序,同时区分大小写, 满足下面的关系:A < a
Exp: 关于str.size() 函数计算的长度,
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str1;
- string str2;
- cout<<str1.size()<<endl;
- cout<<sizeof("")<<endl;
- return ;
- }
执行结果如下所示:
- [root@localhost cpp_src]# g++ test.cpp
- [root@localhost cpp_src]# ./a.out
通过上面的例子可见, str.size()函数计算长度的时候并不包括最后的null字符'\0', 这一点需要注意。
还有一个特殊的地方: 就是 sizeof对 str对象的计算,得到的结果,与str.size 得到的结果不一样,
因此需要注意。如下代码所示:
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str1;
- string str2;
- cout<<str1.size()<<endl;
- cout<<sizeof("")<<endl;
- cout<<sizeof(str1)<<endl;
- return ;
- }
上面代码的执行结果如下所示:
- [root@localhost cpp_src]# g++ test.cpp
- [root@localhost cpp_src]# ./a.out
这里是因为 string对象会保留4个字节来存储string对象的长度。
Exp: 关于 str.empty()函数的使用
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str1;
- string str2;
- if(str1.empty())
- {
- cout<<"str1 is a empty string"<<endl;
- }
- else
- {
- cout<<"str1 is not a empty string"<<endl;
- }
- return ;
- }
执行结果如下:
- [root@localhost cpp_src]# g++ test.cpp
- [root@localhost cpp_src]# ./a.out
- str1 is a empty string
这里可以知道的是,如果string对象是一个空字符串,那么 str.empty()函数返回true。
其实也可以通过 str.size( )==0 来判断string对象是不是为空。因为 str.size()不会计算最后的 ‘\0'.
Exp: 关于 str[n] 的使用
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str1;
- str1="volanol";
- for(string::size_type i=; i != str1.size(); i++)
- {
- cout<<str1[i]<<endl;
- }
- return ;
- }
执行结果如下:
- [root@localhost cpp_src]# ./a.out
- v
- o
- l
- a
- n
- o
- l
这个代码使用了上面说的: str1 = 字符串字面值的赋值方法, 同时使用了 str[n]的下标引用方法。
这里有一点需要说明: string::size_type 是定义在string库中的类型,这个类型专门用来计算string的长度
的。 同时还有一点: string对象的下标从0开始,到 str.size - 1 结束,就是说: 0<= n <= str.size() - 1
str[n]的下标还可以作为左值。如下所示:
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str("volcanol");
- cout<<"str is:"<<str<<endl;
- cout<<"after str[3]='y' the str is:";
- str[]='y';
- cout<<str<<endl;
- return ;
- }
执行结果如下:
- [root@localhost cpp_src]# ./a.out
- str is:volcanol
- after str[]='y' the str is:volyanol
Exp: 关于字符串的相加 str1 + str2
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str1;
- string str2("hi,");
- str1="volanol";
- string str3= str2+ str1;
- cout<<str3<<endl;
- return ;
- }
执行结果如下所示:
- [root@localhost cpp_src]# g++ test.cpp
- [root@localhost cpp_src]# ./a.out
- hi,volanol
这段代码,演示了 string类型的 str1 + str2 的效果,同时演示了 string str("volcanol"); 这样的直接初始化
方式。
string对象的 + 操作可以与字符串字面值进行操作,如下:
Exp:
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str1;
- string str2("hi,");
- str1="volanol";
- string str3= str2+ str1;
- cout<<str3<<endl;
- string str4= str3 + "nice to meet you"; //字符串字面值 + 运算
- cout<<str4<<endl;
- return ;
- }
执行结果如下:
- [root@localhost cpp_src]# g++ test.cpp
- [root@localhost cpp_src]# ./a.out
- hi,volanol
- hi,volanolnice to meet you
同时需要注意的是: + 操作符使用的时候,其左、右操作必须有一个是 string对象,否则是错误的。
例如:
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str1;
- string str2("hi,");
- str1="volanol";
- str1 = "hi," + str1;
- str2= "hi,"+"volcanol";
- cout<<str1<<endl;
- cout<<str2<<endl;
- return ;
- }
编译的情况如下所示:
- [root@localhost cpp_src]# g++ test.cpp
- test.cpp: In function ‘int main()’:
- test.cpp:: 错误:操作数类型 ‘const char []’ 和 ‘const char []’ 对双目 ‘operator+’ 而言无效
- [root@localhost cpp_src]#
可以发现 18 行出现错误了, 说 const char[4] 和 const char [9] 不能用双目运算符进行计算,
原因上面的提示信息已经说的很明白了,const char类型不支持+ 操作。
关于书中的习题:
1、什么是默认构造函数
默认构造函数是类构造对象是默认调用的构造函数,如果用户不编写用户自定义的构造函数,则系统
默认会提供一个默认的构造函数。
2、例举三种初始化string对象的方法
A: string str; 默认构造函数
B : string str("volcnaol"); 利用字符串字面值直接初始化
string str1(str); 利用string对象直接初始化
C string str = "volcanol"; 利用字符串字面值复制初始化
string str1 = str; 利用string对象复制初始化
D: string str(3, 'c');
方法D的例子如下:
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str(,'');
- cout<<str<<endl;
- return ;
- }
执行结果如下:
- [root@localhost cpp_src]# g++ test.cpp
- [root@localhost cpp_src]# ./a.out
3、 下面 s和s1的值分别是什么
- string s;
- int main()
- {
- string s1;
- }
这里 s和s1 都是空字符串, 这个地方考察了一个知识点未初始化的对象的初值是什么。 string对象
不初始化就是空字符串。
- int a;
- int main()
- {
- int b;
- }
如上面所示, 则 a = 0; 而b将会是一个随机值。 这是因为全局的内置类型如果不初始化,则系统默认会
初始化为0, 而局部变量的内置类型就会是一个随机值。因此变量在定义的时候最好要初始化一下,保证在使用
之前就是有一个值,可以避免一些莫名其妙的错误。
习题4、编写程序实现从标准输入每次读入一行文本, 然后改下程序每次读入一个单词。
读入一行的程序:
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str;
- getline(cin,str);
- cout<<str<<endl;
- return ;
- }
修改为读入一个单词:
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str;
- //getline(cin,str);
- cin>>str;
- cout<<str<<endl;
- return ;
- }
习题5: 编写一个程序读入两个字符串,测试是否相等,如果不相等,则指出哪一个较大; 测试两个是否等长,
如果不等长,则指出哪一个较长。
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str1;
- string str2;
- cin>>str1>>str2;
- cout<<"str1 is:"<<str1<<endl;
- cout<<"str2 is:"<<str2<<endl;
- if(str1==str2)
- cout<<"str1 == str2"<<endl;
- else if(str1 > str2)
- cout<<"str1 > str"<<endl;
- else
- cout<<"str1 < str2"<<endl;
- if(str1.size() == str2.size())
- cout<<"str1 and str2 have same length"<<endl;
- else if(str1.size() > str2.size())
- cout<<"str1 is longger than str2"<<endl;
- else
- cout<<"str1 is shorter than strw"<<endl;
- return ;
- }
习题6: 编写一个程序读入多个string对象,然后连接成1个更大的string对象输出; 然后改下程序,将相邻的string对象
用空格隔开。
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str1;
- string str2;
- string str3;
- string str4;
- cin>>str1>>str2>>str3>>str4;
- string str5;
- str5=str1 + str2 + str3 + str4;
- cout<<str5<<endl;
- return ;
- }
修改后的程序:
- [root@localhost cpp_src]# cat test.cpp
- #include <iostream>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- int main()
- {
- string str1;
- string str2;
- string str3;
- string str4;
- cin>>str1>>str2>>str3>>str4;
- string str5;
- str5=str1 +" "+ str2+" " + str3+" " + str4;
- cout<<str5<<endl;
- return ;
- }
7、下面的程序合法吗,实现什么功能
- string s;
- cout<<s[]<<endl;
合法,这个程序最终会输出一个换行号。
这个地方尤其要注意,我开始的时候也做错啦,经过测试才知道是对的。
最后一个题目不做啦,下次补上。
C++_系列自学课程_第_4_课_string_《C++ Primer 第四版》的更多相关文章
- C++_系列自学课程_第_7_课_数组_《C++ Primer 第四版》
说到数组,大家应该都很熟悉,在C.Pascal.Java等语言中,都有数组的概念.在C++中也提供了对数组的支持.数组简单来说就是一堆相同 数据类型对象的集合. 这里要把握住两个要点: 相同的数据类型 ...
- C++_系列自学课程_第_6_课_bitset集_《C++ Primer 第四版》
在C语言中要对一个整数的某一个位进行操作需要用到很多的技巧.这种情况在C++里面通过标准库提供的一个抽象数据类型 bitset得到了改善. 一.标准库bitset类型 1.bitset的作用 bits ...
- C++_系列自学课程_第_5_课_vector容器_《C++ Primer 第四版》
再一次遇到 vector 这个单词; 每一次见到这个单词都感觉这个单词非常的 "高大上"; 数字遇到vector马上就可以360度旋转: 当 "电" 遇到vec ...
- C++_系列自学课程_第_3_课_变量和基本类型_《C++ Primer 第四版》
最近复习C++相关内容,决定在这里记录自己复习的过程. 以前写过部分文字,但是没有坚持连续写,因此学完后 基本又忘光啦,主要是没有实践,这一次决定自学完后,在这里在复习一遍增强自己的记忆和理解程度. ...
- C++_系列自学课程_第_12_课_结构体
#include <iostream> #include <string> using namespace std; struct CDAccount { double bal ...
- C++_系列自学课程_第_12_课_语句_《C++ Primer 第四版》
前面的文章说完了表达式和类型转换的部分内容,在我参考的书里面,接下来讨论的是各种语句,包括:顺序语句.声明语句.复合语句(块语句).语句作用域 .if语句.while语句.for语句.do...whi ...
- C++_系列自学课程_第_11_课_类型转换_《C++ Primer 第四版》
上次说了关于表达式的一些内容,说到还有一些关于数据类型转换的内容,今天我们接着八一八C++中的数据类型转换. 一.隐式类型转换 在表达式中,有些操作符可以对多种类型的操作数进行操作, 例如 + 操作符 ...
- C++_系列自学课程_第_10_课_表达式_《C++ Primer 第四版》
程序设计语言中大部分程序都在进行表达式的求值操作, 例如求两个数的和,求一个表达式的逻辑结果,或者通过输入输出表达式语句进行输入和输出. 这里我们对表达式进行讨论. 一.表达式 1.表达式 表达式由一 ...
- C++_系列自学课程_第_9_课_C语言风格字符串_《C++ Primer 第四版》
前面说了写关于数组和指针的内容,这次在这里讨论一下字符串,讨论一下C语言风格的字符串. 在C语言里面我们利用字符数组来对字符串进行处理, 在C++里面我们前面说过一种类类型string可以对字符串进行 ...
随机推荐
- 掀起你的盖头来:Unit Of Work-工作单元
写在前面 阅读目录: 概念中的理解 代码中的实现 后记 掀起了你的盖头来,让我看你的眼睛,你的眼睛明又亮呀,好像那水波一模样:掀起了你的盖头来,让我看你的脸儿,看看你的脸儿红又圆呀,好像那苹果到秋天. ...
- Azure Table storage 基本用法 -- Azure Storage 之 Table
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table,其中的 Table 就是本文的主角 Azure Tabl ...
- 自定义 checkbox 新玩法 ?
自定义 checkbox 新玩法 ? 第一步:selector 编写 drawable/selector_checkbox_voice.xml <?xml version="1.0&q ...
- css双飞翼布局
双飞翼布局是一种比较灵活的布局,始于淘宝UED,玉伯提出的,他着重介绍的是双飞翼栅格布局. 三列布局为"双飞燕"布局,可以把三栏比作一只鸟,main部分相当是于鸟的身体,而lef ...
- java线程 公平锁 ReentrantLock(boolean fair)
一.公平锁 1.为什么有公平锁 CPU在调度线程的时候是在等待队列里随机挑选一个线程,由于这种随机性所以是无法保证线程先到先得的(synchronized控制的锁就是这种非公平锁).但这样就会产生饥饿 ...
- List-style-type属性失效
异常处理汇总-前端系列:http://www.cnblogs.com/dunitian/p/4523015.html 看重点: 根本原因:padding: 0 0 0 0px; 解决:list-sty ...
- jQuery动画的实现
没有引入deferred机制,其余流程都有了 //////////// //创建动画缓动对象 // //////////// function Tween(value, prop, animation ...
- OpenCASCADE Gauss Integration
OpenCASCADE Gauss Integration eryar@163.com Abstract. Numerical integration is the approximate compu ...
- 深入理解脚本化CSS系列第三篇——脚本化CSS类
前面的话 在实际工作中,我们使用javascript操作CSS样式时,如果要改变大量样式,会使用脚本化CSS类的技术,本文将详细介绍脚本化CSS类 style 我们在改变元素的少部分样式时,一般会直接 ...
- mac下安装tomcat
在window下面搭建tomcat环境很简单,那是因为我们不熟悉mac系统,当我们习惯了命令行的时候,也是so easy,只要通过以下几个步骤就可以解决,本人亲测可用,不会可以留言. 1.进入apch ...