C++ Primer第三章②

C++ Primer

第三章 字符串、向量和数组

标准库类型string

string表示可变长的字符序列,使用string必须包含下述代码:

#include 
using std::string;

定义和初始化string对象

string s1; //s1默认初始化,是一个空字符串
string s2 = s1; //s2是s1的副本
string s3(s2); //s3是s2的副本
string s4 = "hello"; //字符串字面值赋值
string s5(3, 'c'); //s5 = "ccc";

对于s1我有个小问题,s1和""相等吗?于是我试了下

string a;
string b = "";
if(a == b)
{
    cout << "equal" << endl;
}

答案是相等的。

下面来看一个我觉得很累赘的定义

直接初始化和拷贝初始化
string s6 = "world"; //拷贝初始化
string s7("heihei"); //直接初始化
string s8(3, 'c'); //直接初始化

不知道大家发现规律没,如果原来内存中已经有一个对象,例如"world"字面值常量,然后把这个对象的内容拷贝给string,那就是拷贝初始化,如果没有,就是直接初始化,相当于说:直接初始化吃新鲜的,拷贝初始化吃人家吐给你的。 下面来判断一下:

string s9 = string(10, 'c'); //拷贝初始化,因为等号右边创建了一个临时对象,s9吃的是临时对象吐给它的

string对象上的操作

一个类除了要规定初始化其对象的方式外,还要定义对象上所能执行的操作。

读写string
int main()
{
    string s;
    cin >> s;
    cout << s << endl;
    return 0;

这段代码先定义一个空字符串s,然后将标准输入的内容读取到s中。在执行读取操作时,string对象会自动忽略开头的空白(空格,换行,制表)并从第一个真正的字符开始读起,直到遇见下一处空白为止。 如上所述,如果输入" hey zhou ",输出将是"hey",不信你自己试试。 string对象也支持连续输入输出(这个是cin和cout的特性,以后会介绍原理)

string s1, s2;
cin >> s1 >> s2; //第一个输入到s1,第二个输入到s2
cout << s1 << s2 << endl; //输出两个string对象

这段程序如果输入" hey zhou ",输出是"heyzhou" 只有这样的一种输入方式肯定不够,因为它只能读取数量确定的一个一个的单词。

读取未知数量的string

给你个代码自己体会

int main()
{
    string word;
    while(cin >> word)
    {
        cout << word << endl;
    }
    return 0;
}

有时候,我们还希望能在最终得到的字符串中保留输入的空白符,这时应该用getline函数代替>>。

int main()
{
    string line;
    while(getline(cin, line))
    {
        cout << line << endl;
    }
    return 0;
}
size函数和empty函数

顾名思义就好了,调用非常简单,这两个函数也非常实用,下面我写个程序,打印多行字符中非空的,且字符数量小于20的,通过这段代码你就能了解size和empty的用法

int main()
{
    string line;
    while(getline(cin, line))
    {
        if( !line.empty() && line.size()<20 )
        {
            cout << line << endl;
        }
    }
}

很明显,我们可以看到,empty()返回的是布尔类型,那么size函数返回的是int吗?如果是int,那我们之前提过,int在不同机器上的大小是不一样的,所以,这里C++的设计者搞了种新的数据类型size_type,它是无符号类型,就是非负数,可以做到机器无关,那么我们要这么繁琐地写这么多字母吗?不用的,别忘了我们有神器

auto len = line.size() //len的类型是string::size_type
比较string对象

书上的规则说起来太麻烦,直接贴代码聪明的读者就知道了啊

string s1 = "hello";
string s2 = "hello jay";
string s3 = "hi";

s1<s2<s3.

为string对象赋值
string str = "Hello", str1;
str1 = str; //str1初始化的时候是空字符串,现在被赋值后是"Hello",这个跟直接string str1 = "Hello"还是有区别的
两个string对象相加
string s1 = "Hello", s2 = " jay";
s1 += s2; //s1 = s1 + s2,s1的内容变为hello jay
字面值和string对象相加

准则:当把string对象和字符字面值及字符串字面值混在一条语句中时,必须确保每个加法运算符两侧的运算对象至少有一个是string:

string s1 = "hello", s2 = "jay";
string s3 = s1 + ", " + s2; //正确
string s4 = "hello" + "jay"; //错误:两个运算对象都不是string
string s5 = s1 + ", " + "jay"; //正确:第一个加号的结果就是string
string s6 = "hello" + ", " + s2; //错误

处理string对象中的字符

这个问题分两个:

  1. 处理单个字符: 比如检查一个string对象是否包含空白,或者把大写改为小写
  2. 如何获取字符本身: 有时需要处理所有字符,有时需要处理某个特定字符 关于第一个问题,除了你自己处理之外,C++中的cctype文件提供了很多方便的函数供你调用,如下图:
处理每个字符

比如每行输出str中的一个字符

string str("hey jay");
for(auto c : str)
{
    cout << c << endl;
}

这里用auto来决定c的类型,这里c是char,每次迭代,str的下一个字符被拷贝给c

来个复杂点的例子,统计一个string对象中标点符号的个数:

string s("hello, this is mike, nice to meet you.");
decltype(s.szie()) cnt = 0;
for(auto c : s)
{
    if(ispunct(c))
    {
        ++cnt;
    }
}
cout << "标点符号的个数是" << cnt << endl;

不解释啦。

如果我想把一个string对象中的小写字母都改成大写呢?,看看下面的代码对不对

string s("hello");
for(auto c : s)
{
    c = toupper(c);
}
cout << s << endl;

很遗憾,是错的,因为c是由s中的字符拷贝过去的,意思就是,s里面有很多小苹果,c没从里面拿苹果,而是拷贝了其中一个小苹果,然后把这个拷贝的苹果变大了,跟s没啥关系。 其实只需要改一个地方就好

string s("hello");
for(auto &c : s)
{
    c = toupper(c);
}
cout << s << endl;

这时c没有去拷贝苹果,c就是里面那些小苹果的绰号,代表本身,这时就能愉快打印出"HELLO"了。

以上是我们在处理string中所有字符的情况,只处理一部分字符呢?

只处理一部分字符——>下标运算符[ ]

例如,我们只想把字符串中第一个字符改为大写,其他不变

string s("some thing");
if(!s.empty()) //别忘了这个条件啊,提升代码健壮性
{
    s[0] = toupper(s[0]); //Some thing
}

那[ ]符号中的数是什么类型的呢?是int吗?不是的,是string的size_type, 如果某个索引是带符号类型的值将自动转换成string的size_type。

来个难点的,编写一个程序把0-15之间的十进制数转换成对应的十进制数(可以自己先想想先写写)

const string hex = "0123456789ABCDEF";
string res;
string::size_type n;
while(cin >> n)
{
    if(n < 16)
    {
        res += hex[n]; //是不是很巧妙
    }
    cout << res << endl;
}
全部评论
最后那个是转换为对应的16进制是吧
点赞 回复 分享
发布于 2018-10-03 12:03
定义的空字符串和"",应该是相等的吧!!!
点赞 回复 分享
发布于 2017-02-22 11:15

相关推荐

upLuck:比我强查看图片
点赞 评论 收藏
分享
评论
8
7
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务