C++primer笔记-第3章 字符串、变量和数组(标准库类型string)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liaoyanyunde/article/details/83718438

 标准库string、vector都是对内置数组类型的抽象,string支持变长的字符串,vector表示可变长的集合。迭代器是string和vector的配套类型,常用于访问string或者vector中的元素。

string作为标准库的一部分,定义在命名空间std中。

#include <string>
using namespace std::string;

1、定义和初始化string对象

 string实际上是一个类,类对象的初始化都是由类中的构造函数决定的。string具有很多种初始化方式。默认初始化为空字符串。

带等号的是拷贝初始化,其他的是直接初始化

string s1;  //默认初始化,s1是一个空字符串
string s2(s1);  //s2是s1的副本  直接初始化
string s2=s1;  //等价于s2(s1)    拷贝初始化
string s3("value");  //s3是字面值"value"的副本,除了字面值最后的那个空字符‘\0’外  直接初始化
string s3="value"; //等价于s3("value")  拷贝初始化
string s4(n,'c');  //把s4初始化为由连续n个字符c组成的字符串

2、string对象上的操作

2.1 读写string对象-标准输入输出 >> <<

string s;  //空字符串
cin>>s;  //将string对象读入s,遇到空白位置
cout<<s<<endl; //输出s

使用cin输入string的时候,从第一个字符到第一个空白(包括空格、换行、制表符等)为止。

如果上程序输入“    hello word!   ”
输出的将是 “hello”
可以连续输入

string s1,s2; 
cin>>s1>>s2;  
cout<<s1<<s2<<endl;

如果上程序输入“    hello word!   ”
输出的将是 “helloword!”

2.2 使用getline读取一整行

getline输入string对象,可保留空白符,遇到换行符为止(换行符也读进去了,但是不保存到string对象中

string line;
while(getline(cin,line)){  //遇到换行符,则输入一次string对象
      cout<<line<<enld
}

 getline第一个参数是输入流。使用该参数之前,如果该参数做过输入的操作则会影响getline的输入,因此需要清除cin的缓冲区。
 如下述代码所示:
 如果输入的type是2,则getline获取的内容就是换行符,最终输出的是字符串。
 原因分析:cin的时候会产生一个缓冲区,执行cin>>type时输入2和换行符,缓冲区中有:2和换行符,此时2写入到type中,cin缓冲区中还有换行符,使用geiline(cin,line)的时候,cin中遇到换行符结束输入,将空字符串写入到line中。
 解决这个问题的方法是,getline使用cin之前情况cin的缓冲区
 cin.clear();
 cin.sync();

	string word,line;
	cout<<"请选择读取字符串的方式,1是逐词读取;2是按行读取."<<endl;
	char type;
	cin>>type;
	if(type=='1'){
		cout<<"请输入字符串:			Welcome to c++ family!  "<<endl;
		cin>>word;
		cout<<word<<endl;
	}
	//清空输入缓冲区
	//cin.clear();
	//cin.sync();
	if(type=='2'){
		cout<<"请输入字符串:			Welcome to c++ family!  "<<endl;
		getline(cin,line);

		cout<<line<<endl;
	}
	cout<<"输入有误!"<<endl;
	system("pause");

在这里插入图片描述在这里插入图片描述

 为什么输入1的时候,不会出现这个问题呢?
 因为cin方式输入字符串的时候是从第一个字符到第一个空白结束。当输入1和换行符时,cin缓冲区中有1和换行符,然后将1写入到type中,cin缓冲区中还剩下换行符,但是因为继续cin输入时是从遇到的第一个字符开始算到所以可以继续输入

2.3 string的empty和size操作

empty()判断字符串是否为空,为空则但会true 不为空则返回false.

while(getline(cin,line)){
	if(!line.empty()){
	cout<<line<<endl;
}
}

size()函数返回string对象的长度(即字符个数),返回值类型是无符号整数最好不要与有符号数混用!!!!
 size()函数返回值的类型是string::size_type类型,该类型实际就是与机器无关的无符号整形,可以放下任何string对象的大小。所以使用该函数返回值的时候要注意,不能跟带符号混用,可能会产生意想不到的错误。
 假设n为负数,则s.size()<n 永远是true,因为负数n会自动转换成为一个比较大的无符号值。

2.4 string对象比较

可使用==、!==、 <、 <=、 >、 >= 对string对象进行比较

==意味着string对象长度相等且每个字符也相等

string对象比较,先比较长度 在逐个比较字符

2.5 string对象相加

 两个string对象相加,并没有什么特别的,就是字符串拼接在一起。如下述代码所示

string s1="hello,",s2="world\n";
string s3=s1+s2; 
cout<<s3<<endl; //s3的内容是“hello,world\n”
s1+=s2; //等价于 s1=s1+s2

 如果是字面值跟string对象相加,则需要注意:
string对象一定要在前面且至少要有一个string对象

 字符串字面值并不是string对象!

string s4=s1+"primer"; //正确
string s5="hello,"+"world\n";//错误。因为两个对象都不是string对象
string s5="hello,"+s1;//错误。string对象跟字面值相加,string对象要放在前面
string s5=s1+"world\n";//正确

3、处理字符串中的字符

 处理string对象中每个字符,c++标准库中提供了cctype,用于对字符的属性进行处理或者判断。
 但需要注意的是,cctype中提供的函数都没有判断字符的合法性,如果传入的字符是中文或者不在-1和255之间,则会报错。

  • isalnum(c) 当c是字母或者数字时为真 isalpha( c ) 当c是字母时为真
  • iscntrl(c)当c是控制字符时为真
  • isdigit(c) 当c是数字时为真
  • isgraph(c) 当c不是空格但可打印时为真
  • islower(c)当c是小写字母时为真
  • isprint(c) 当c是可打印字符时为真(即c是空格或者c具有可视形式)
  • ispunct(c) 当c是标点符号时为真(即c不是控制字符、数字、字母、可打印空白中的一种)
  • isspace(c) 当c是空白时为真(即c是空格、横向制表符、纵向制表符、回车符、换行符、进纸符中的一种)
  • isupper(c) 当c是大写字母时为真
  • isxdigit(c) 当c是十六进制数字时为真
  • tolower(c) 如果c是大写字母。则将字符c转换成小写字母。否则原样输出
  • toupper(c) 如果c是小写字母,则将字符c转换成大写字母,否则原样输出

ps:在ASCII码中,第0~31号及第127号(共33个)是控制字符或通讯专用字符,如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(振铃)等;通讯专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等。

遍历string对象中的字符

string str="hello";
for(auto ch:str){
	cout<<ch<<endl;
}
string str="hello";
auto size = str.size();
for(decltype(str.size()) i =0 ; i<size; i++){ 
	cout<<str[i] <<endl;
}
string str = "hello";
	auto begin = str.begin();
	auto end = str.end();
	while (begin != end) {
		cout << *begin << endl;
		begin++;
	};

改变string中字符的值
要改变string对象中字符的值,必须使用引用(下标取值返回的也是引用)或者迭代器

//使用引用
string str="hello";
for(auto &ch:str){ 
	ch='w';
}
//使用下标
string str="hello";
auto size = str.size();
for(decltype(str.size()) i =0 ; i<size; i++){ 
	str[i] = 'w';
}
//使用迭代器
string str = "hello";
auto begin = str.begin();
auto end = str.end();
while (begin != end) {
	*begin ='w';
	begin++;
};
cout << str << endl;

使用下标访问时尤其要注意不要越界了!!

猜你喜欢

转载自blog.csdn.net/liaoyanyunde/article/details/83718438