c++的字符串、向量和数组

命名空间的using声明

目前用到的库函数基本上都属于命名空间std;通过using声明(using declaration)实现更简单的途径使用到命名空间中的成员。

标准库类型string

string表示可变长的字符序列,必须先包含string头文件(#include <string>);作为标准库的一部分,string定义在命名空间std中。

定义和初始化string对象:

string s1;//默认初始化,s1是一个空字符串
string s2(s1);//s2是s1的副本
string s2 = s1;//等价于上式
string s3 = "hiya";//s3是该字符串字面值的副本,除了字面值最后的那个空字符外
string s4(10, 'c');s4的内容是cccccccccc

直接初始化和拷贝初始化:如果使用等用(=)初始化一个变量,实际上执行的是拷贝初始化,编译器把等号右侧的初始值拷贝到新建的对象中去;与之相反,如果不使用等号,则执行的是直接初始化。

string s5 = "hiya";//拷贝初始化
string s6("hiya");//直接初始化
string s7(10, 'c');//直接初始化,s7的内容是cccccccccc

string对象上的操作:

操作解释
os<<s将s写到输出流os当中,返回os
is>>s从is中读取字符串赋给s,字符串以空白分隔,返回is
getline(is, s)从is中读取一行赋给s,返回is
s.empty()s为空返回true,否则返回false
s.size()返回s中字符的个数
s[n]返回s中第n个字符的引用,位置n从0计起
s1+s2返回s1和s2连接后的结果
s1=s2用s2的副本代替s1中原来的字符

s1==s2

如果s1和s2中所含的字符完全一样,则它们相等,string对象的相等性判断对字母的大小写敏感
s1 != s2不相等判断
<, <=, >, >=利用字符在字典中的顺序进行比较,且对字母的大小写敏感

读写string对象

c++中使用标准库中的iostream来读写int、double等内置类型的值,同样也可以使用IO操作符来读写string对象。

string对象会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇见下一处空白为止

#include <iostream>
using namespace std;

int main()
{
    string s;
    cin >> s;
    cout << s << endl;

    return 0;
}

/*
    如果程序的输入是“    Hello World!    ”(注意开头和结尾处的空格),则输出将是“Hello”,输出结果没有任何空格。
*/

string对象多个输入或者多个输出可以连写在一起;如下面代码,输入是“    Hello  World!    ”,则输出是“HelloWorld!”。

#include <iostream>
using namespace std;

int main()
{
    string s1, s2;
    cin >> s1 >> s2;
    cout << s1 << s2 << endl;

    return 0;
}
//输入是“    Hello  World!    ”,则输出是“HelloWorld!”。

getline使用

想要在最终得到的字符串中保留输入时的空白符,应该用getline函数代替原来的>>运算符;getline函数的参数是一个输入流和一个string对象,函数从给定的输入流中读入内容,直到遇到换行符为止,此时换行符也被读进来;然后把所读的内容存入到那个string对象中去,此时不存换行符。

getline函数只要一遇到换行符就结束读取操作并返回结果,即使一开始输入就是换行符也是如此。

string的empty和size操作

empty函数 根据string对象是否为空返回一个对应的布尔值;empty是string的一个成员函数,使用点操作符指明是哪个对象执行了empty函数即可。

//每次读入一整行,遇到空行直接跳过
while(getline(cin, line))
    if(!line.empty())
        cout << line << endl;

size函数返回string对象的长度,即string对象中字符的个数。

size函数返回的是一个无符号整型数,因此在一条表达式中如果有了size函数就不要再使用int了,这样可以避免混用int和unsigned可能带来的问题。

比较string对象

相等性运算符(==和!=):分别检验两个string对象相等或不相等,意味着长度相同且所包含的字符也全相同。

关系运算符(<、<=、>、>=):分别检验一个string对象是否小于、小于等于、大于、大于等于另外一个string对象。

注意:

如果两个string对象的长度不同,而且较短string对象的每个字符都与较长string对象对应为止上的字符相同,则较短string对象小于较长string对象。

如果两个string对象在某些对应的位置上不一致,则string对象比较的结果其实是string对象中第一对相异字符的比较结果。

string对象相加

两个string对象相加:

两个string对象相加得到一个新的string对象,其内容是把左侧的运算对象与右侧运算对象串接起来。

字面值和string对象相加:

标准库允许把字符字面值和字符串字面值转换成string对象。 

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

string s1 = "hello";
string s2 = "world";

string s4 = s1 + ", ";//正确
string s5 = "hello" + ", "; //错误:两个运算对象都不是string

string s6 = s1 + ", " + "world";//正确
string s7 = "hello" + ", " + s2;//错误:不能把字面值直接相加

处理string对象中的字符

cctype头文件中定义了一组标准库函数来处理string对象中的字符。

 处理string对象中的每个字符,使用基于范围的for语句。

string str("some string");//每行输出str中的一个字符

for(auto c : str)
    cout << c << endl;//输出当前字符,后面紧跟一个换行符

想改变string对象中字符的值,必须把循环变量定义成引用类型。

string s("Hello World!!!");

//转换成大写形式
for(auto &c : s)
    c = toupper(c);//c 是一个引用,因此赋值语句将改变s中字符得到值
cout << s << endl; 

只处理string对象中一部分字符,用下标运算符([])

string s("some string");
if(!s.empty()){
    s[0] = toupper(s[0]);//将第一个字符变成大写
}

//返回 Some string

标准库类型vector

标准库类型vector表示对象的集合,其中所有对象的类型都相同。

集合中的每个对象都有一个与之对应的索引,索引用于访问对象。

因为vector容纳着其他对象,所以它也常被称为容器(container)。

想要使用vector,包含头文件#include <vector>。

#include <vector>
using namespace std
main()
{
    vector<int> ivec;//ivec保存int类型的对象
    vector<Sale_item> Sales_vec;//保存Sales_item类型的对象
    vector<vector<string>> file; //该向量的元素是vector对象

    return 0;
}

定义和初始化vector对象

//列表初始化vector对象
vector<string> v1 {"a", "an", "the"};//列表初始化
vector<string> v2 ("a", "an", "the");//错误

//创建指定数量的元素
vector<int> ivec(10, -1);//10个int类型的元素,每个都被初始化为-1

//值初始化
vector<int> ivec2(10);//10个元素,每个都被初始化为0
vector<string> svec(10);//10个元素,每个都是空string对象


//列表初始值还是元素数量
vector<int> v3(10);//v3有10个元素,每个的值都是0
vector<int> v4{10};//v4有1个元素,该元素值是10

 向vector对象中添加元素

利用vector的成员函数push_back向其中添加元素,push_back负责把一个值当成vector对象的尾元素“压到push”vector对象的“尾端(back)”。

string word;
vector<string> text;
while(cin >> word){
    text.push_back(word);//把word添加到text后面
}

vector其他操作

操作解释
v.empty()如果v不含有任何元素,返回真,否则返回假
v.size()返回v中元素的个数
v.push_back(t)向v的尾端添加一个值t的元素
v[n]返回v中第n个位置上元素的引用
v1 = v2用v2中元素的拷贝替换v1中的元素
v1 = {a, b, c...}用列表中元素的拷贝替换v1中的元素
v1 == v2v1和v2相等,数量和对应位置的元素值都相同
v1 != v2
<、<=、>、>=以字典顺序进行比较

迭代器介绍

可以使用下标运算符来访问string对象的字符或vector对象的元素,还有另外一种更通用的机制,即迭代器(iterator)

标准库容器都可以使用迭代器

和指针不一样的是,获取迭代器不是使用取地址符,有迭代器的类型同时拥有返回迭代器的成员。

迭代器也提供了对对象的间接访问,就迭代器而言,其对象是容器中的元素或者string对象中的字符;使用迭代器可以访问某个元素,迭代器也能从一个元素移动到另外一个元素。

操作解释
*iter返回迭代器iter所致元素的引用
iter->men解引用iter并获取该元素的名为men的成员,等价于(*iter).men
++iter令iter指示容器中的下一个元素
--iter令iter指示容器中的下一个元素
iter1 == iter2判断两个迭代器相等
iter1 != iter2判断两个迭代器不相等
string s("some string");
if(s.begin() != s.end()){
    auto it = s.begin();//it表示s的第一个字符
    *it = toupper(*it) //将当前字符改写成大写形式
}

//返回 Some string,跟下标运算符功能一样

数组

数组是一种类似与标准库类型vector的数据结构,与vector相似的地方是数组也存放类型相同的对象的容器,这些对象本身没有名字,需要通过其所在位置访问;与vector不同的地方是,数组的大小确定不变,不能随意向数组中增加元素。

如果不清楚元素的确切个数,使用vector。

定义和初始化内置数组

数组的声明形如a[d],其中a是数组的名字,d是数组的维度,维度说明了数组中元素的个数,因此必须大于0;维度d必须是一个常量表达式。

定义数组的时候必须指定数组的类型,不允许用关键字auto由初始值的列表推断类型。

显式初始化数组元素:对数组的元素进行列表初始化,此时允许忽略数组的维度。

字符数组的特殊性:字符数组有一种额外的初始化形式,可以用字符串字面值对此列数组初始化;当使用这种方式时,一定要注意字符串字面值的结尾处还有一个空字符,这个空字符也会向字符串的其他字符一样被拷贝到字符数组中。

/*
  a1维度是3,a2和a3维度是4,a4定义是错误的
*/
char a1[] = {'c', '+', '+'};//列表初始化,没有空字符
char a2[] = {'c', '+', '+', '\0'};//列表初始化,含有显式的空字符
char a3[] = "c++";//自动添加表示字符串结束的空字符
const char a4[6] = "Daniel";//错误:,没有空间存放空字符

不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值。

int a[] = {1, 2, 3};
int a2[] = a;//错误:不允许使用一个数组初始化另外一个数组
a2 = a;//错误:不能把一个数组直接赋值给另外一个数组

访问数组元素

和标准库vector和string一样,数组的元素也能使用范围for语句或下标运算符来访问。

数组的索引从 0  开始。

数组与指针

使用数组的时候编译器一般会把它转换成指针。

对数组的元素使用取地址符就能得到指向该元素的指针。

在用到数组名字的地方,编译器都会自动将其替换为一个指向数组首元素的指针。

string nums[] = {"one", "two", "three"};//数组的元素是string对象
string *p = &nums[0];//p指向nums的第一个元素

string *p = nums;//等价于p2 = &nums[0];

多维数组

C++语言中没有多维数组,通常所说的多维数组其实是数组的数组。

当一个数组的元素仍然是数组时,通常使用两个维度来定义它,一个维度表示数组本身大小,另外一个维度表示其元素(也是数组)大小。

int ia[3][4];//大小为3的数组,每个元素是含有4个整数的数组

 使用双范围for语句来处理多维数组。

当程序使用多维数组的名字时,也会自动将其转换成指向数组首元素的指针。

//多维数组指针申明时,圆括号必不可少
int *ip[4];//整型指针的数组
int (*ip)[4];//指向含有4个整数的数组

参考

C++ Primer(第5版).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Codec Conductor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值