C++及其数据结构学习笔记目录
目录
前言
C++学习笔记第二弹,如有错误请各位大佬不吝指教~
一、使用字符串作为抽象数据
旧版本的C语言对字符串的操作机制被定义在底层运算上,因此,执行相应操作要求理解底层表示。但是C++中的string类允许用户在更抽象的水平上处理字符串。字符串的赋值有两种类型:
1.直接声明
代码如下:
const string xiaren = "Naruto";
2.字符串输入
一般情况下可以通过cin输入流来得到字符串,但是这种方法有一定的局限,原因在于cin输入流的操作符>>在遇到空白字符(包括空格,制表符,段落标志)时就会停止读取。实际操作中,读取一整行字符串这一操作比读取两端被空白字符分隔的字符串更加常见,这个时候更为标准的做法是使用getline(cin,str)函数,将一整行字符串str传入cin。举个栗子,下面是"hello world"程序的高阶版:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Enter your full name:";
getline(cin, name);
cout << "Hello ," << name << "!" << endl;
return 0;
}
二、字符串操作
首先需要明确,string是一个类(class),这种类型被简单的定义为一个包含值集和相应操作集的模板,属于一个类的所有值被称为该类的对象(object),一个类可拥有多个不同对象,每一个对象被称作该类的一个实例(instance)。应用于类实例的操作被称为方法(method),与函数不同,方法与它们所属的类紧密联系,传统的函数通常称为自由函数。
在面向对象程序设计中,对象间通过信息发送和请求来实现对象间的通信,这些信息统称为消息(message)。对象间的消息发送通常理解为一个对象调用属于另一个对象的方法。为了与发送消息的概念模型达成一致,初始化方法的对象称为消息的发送方(sender),消息的目标对象称为接收方(receiver),C++中使用如下语法进行消息的发送:
receiver.name(arguments);
1.操作符重载
str1+str2 | 连接字符串str1和str2,返回一个连接后的新字符串。其中str1和str2可以替换为字符类型,但不允许替换为数字类型。 |
str+=str2 | 将字符串str2的拷贝添加到str的末尾。str2可以为字符类型。 |
str1 ==str2 str1 != str2 str1 <= str2 str1 >= str2 str1 < str2 str1 > str2 | 用于比较字符串str1和str2。比较标准参照字典序,字典序由字符ASCII码值定义,这一部分和str1.compare(str2)方法非常相似,因此,很少有程序员会明确地调用compare方法(直接用操作符)。 |
2.从一个字符串中选取字符
str[k] | 返回字符串str索引位置k上的字符,但是并不检查k是否合法 |
str.at(k) | 基本功能同上,但是会检查k的合法性,不合法会产生异常 |
3.字符串赋值
在执行两个字符串的赋值操作之后,str1和str2依然保持独立,改变str1不会改变str2,除非使用了引用传递符号“&”。
str2 = str1;
int nChars = str1.length();
4.字符串中搜索
str.find(pattern,pos) | 在接收方字符串str中,从pos位置开始查找Pattern子串,如果找到就返回pattern所出现的第一个索引值,如果没有出现就返回string::npos常量。第二个参数可选,默认第二参数为0(从头查找)。 |
5.字符串中字符的循环遍历
代码如下,要熟练掌握
for (int i = 0; i < name.length(); i++) {
cout << name.at(i);
}
6.提取字符串子串
str.substr(pos,n) | 返回一个新的字符串,该字符串从str的pos位置开始,包含n个字符或者直到str字符串末尾的子串。第二个参数可选,默认延伸至字符串末尾。 |
7.修改接受方字符串的方法
str.erase(pos,n) | 从str的pos处开始向后删除n个字符 |
str.insert(pos,str2) | 从str的pos处开始插入str2的拷贝 |
str.replace(pos,n,str2) | 用str2替换str中从pos开始的n个字符 |
三、<cctype>库
该库提供了处理字符串中字符的各种函数。主要包含两类:
1.检验字符类型的判断函数
isalpha(ch),isupper(ch),islower(ch),isdigit(ch),isxdigit(ch),isalnum(ch),ispunct(ch),isspace(ch),isprint(ch)依次判断是否为字母,大写字母,小写字母,数字,16进制数,数字字母混合,标点,空白字符(' ','\t','\n','\f','\v','\r'以及可打印字符。如果是,就返回true。
2.大小写转换函数
toupper(ch);tolower(ch);
注意:如果ch不是一个字母就返回ch本身
四、修改字符串中的内容
大多数情况下,最好编写函数使它们返回一个字符串的装换版本而不改变原有字符串的内容,但是采用循环遍历字符串、迭代拼接的方法显得很笨拙,不妨结合两者,下面给出一个列子。该实例函数完成将字符串转换为全部大写:
方法一:改变原有字符串的值
void toUpperCaseInplace(string & str) {
for (int i = 0; i < str.length(); i++)
{
str.at(i) = toupper(str.at(i));
}
}
方法二:同时使用迭代和连接字符串,不改变原有字符串的值
string toUpperCase(string str) {
string results = "";
for (int i = 0; i < str.length(); i++)
{
results += toupper(str.at(i));
}
return results;
}
方法三:二者结合可以更加高效
string toUpperCase(string str) {
toUpperCaseInplace(str);
return str;
}
五、遗留的C风格字符串
string str = "hello" + "," + "world";
上面的这句代码正确吗?残念だけど、実はそれは違うですよ。此处的问题是该代码版本尝试将+操作符应用到非C++string对象的字符串上面——你没看错:“hello, world"是C风格的字符串字面值,而非string类型的对象,但是
string str = "hello, world";
会自动将C风格的字符串字面值转换为string类型的对象。解决办法就是强制类型转换为string:
string str = string("hello") + "," + "world";
由此对这类函数进行总结如下:
string(carray) | 将C风格字符串字面值装换为string类对象 |
string(n,ch) | 返回一个包含n个字符的C++字符串 |
str.c_str() | 返回一个与str内容同样的C风格字符数组 |
总结
以上就是今天要讲的内容,本文仅仅简单介绍了C++字符串string类的使用,下一章会讲到stream类。