题记:
C++处理提供基本数据类型外,还定义了一个内容丰富的抽象数据类型标准库,包括以下四种标准库类型:string、vector、iterator、bitset,本篇主要讲述string标准库。
5.1 关于命名空间的using声明
- 每个名字都需要一个using声明,且一个using声明一次只能作用于一个命名空间成员。如:
using std::cin;
using std::cout;
using std::endl;
注:在文件中可以直接使用: using namespace std;//这个将std中的所有成员都引用了
- 在头文件中应该使用完全限定的标准库名字,如std::cout<<std:endl;而不应使用如using std::cin;或 using namespace std;的形式。
5.2 标准库string类型
string类型支持长度可变的字符串,用户程序要使用string类型的对象,必须包含相关头文件,即:
#include <string>
using std::string;
string标准库支持几个构造函数来初始化该类型的对象。string类型的几个常见默认构造函数如下:
5.2.1 string对象的读写
1. 使用标准输入输出操作符来读写string对象,注意以下两点:
- 读取并忽略开头所有的空白字符(如:空格、换行符、制表符);
- 读取字符直至再次遇到空白字符为止
程序清单—01
1 #include<iostream> 2 #include<string>//用户要使用string类型,必须添加该头文件 3 using namespace std; 4 int main() 5 { 6 string str;//默认构造函数,str为空 7 cin>>str; 8 cout<<str<<endl; 9 system("pause"); 10 return 0; 11 }
程序结果:
程序输出结果:忽略了开始的所有空格,并且当遇到再次空白时输出停止
2. 读入未知数目的string对象——类似于内置类型的输入操作符,string类型的输入操作符也返回所读的数据流
程序清单—02
该程序将从标准输入流读取一组string对象,然后在标准输出上逐行输出
1 #include<iostream> 2 #include<string>//用户要使用string类型,必须添加该头文件 3 using namespace std; 4 int main() 5 { 6 string str;//默认构造函数,str为空 7 while(cin>>str) 8 cout<<str<<endl; 9 system("pause"); 10 return 0; 11 }
程序结果:
3. 使用getline获取整行文本
- getline函数接受两个参数:一个输入流对象和一个string对象
- getline函数从输入流的下一行读取,并保存读取的内容到string中,但不包括换行符
- getline函数并不忽略行开头的换行符
注:
- 只要getline遇到换行符,即便它是输入的第一个字符,getline也将停止读入并返回
- 如果第一个字符就是换行符,则string将被置为空的string
程序清单—03
1 #include<iostream> 2 #include<string>//用户要使用string类型,必须添加该头文件 3 using namespace std; 4 int main() 5 { 6 string line;//默认构造函数,str为空 7 while(getline(cin,line)) 8 cout<<line<<endl; 9 system("pause"); 10 return 0; 11 }
程序结果:
5.2.2 string对象的操作
表5-1 string对象的相关操作
注意几点:
- string对象的长度是指string对象中字符的个数,可以通过size操作获取。如s.size(),返回s中字符的个数。从而判断string对象为空就有两种方法:
方法1: if(s.size()==0) // ok ,s is empty
方法2: if(s.empty()) // ok ,s is empty
- string对象的size()函数貌似返回的是整型数值,或是unsigned整数,其实不然,事实上,size操作返回的是string::size_type类型的值
string类类型和很多其他库类型都定义了一些配套类型。通过这些配套类型,库类型的使用就能与机器无关。size_type就是这些配套类型中的一种。它定义为与unsigned型具有相同的含义,而且能够保证足够大能够存储任意string对象的长度(这就是不使用int型作为size操作返回值的原因)。
为了使用由string类型定义的size_type类型,必须加上作用域操作符(::)来说明所使用的size_type类型由string类定义的。
- string对象比较操作是区分大小写的,即同一个字符的大小写是两个不同的字符。任何大写字母均小于小写字母
关系操作符比较两个string对象,采用的是字典排序,即:
- 如果两个string对象长度不同,且短的string对象与长的string对象的前面部分相匹配,则短的string对象小于长的string对象
- 如果两个string对象的字符不同,则比较第一个不匹配的字符
- string对象的下标从0开始。string对象的索引变量最好也使用string::size_type类型
程序清单—04
#include <iostream> #include <string> //标准库string类型头文件 #include <cctype> //string对象中字符的处理函数的头文件 using std::string; //string类型的using声明 using std::cin; using std::cout; using std::endl; int main() { int n = 4; string s1; //默认构造函数,s1为空串 string s2(s1); //将s2初始化为s1的一个副本 string s3("value"); //将s3初始化为一个字符串字面值副本 string s4(n, 'c'); //将s4初始化为字符‘c’的n个副本 cout << "string对象的定义和初始化" << endl; cout << "s1: " << s1 << endl; cout << "s2: " << s2 << endl; cout << "s3: " << s3 << endl; cout << "s4: " << s4 << endl; cout << "**************************************** " << endl; cout << "string对象的操作" << endl; string st("I am from JiangSu university "); cout << "The size of st" << "is: " << st.size() << endl; if(!st.size()==0) cout << st.size() << endl; if(!st.empty()) cout << st.size() << endl; s2 = s3; cout << "string对象的赋值,s2=s3,s2:" << s2 << endl; s1 = "hello"; s2 = "world"; s3 = s1 + ", "; s4 = s1 + ", " + "world"; cout << "s1: " << s1 << " size: "<< s1.size() << endl; cout << "s2: " << s2 << " size: "<< s2.size() << endl; cout << "s3: " << s3 << " size: "<< s3.size() << endl; cout << "s4: " << s4 << " size: "<< s4.size() << endl; for(string::size_type ix=0; ix!=s4.size(); ++ix) //string对象的索引最好使用string::size_type类型 cout << s4[ix] << endl; for(string::size_type ix=0; ix!=s4.size(); ++ix) s4[ix]='*'; cout << "s4: " << s4 << " size: "<< s4.size() << endl; cout << "**************************************** " << endl; system("pause"); return 0; }
程序结果:
5.2.3 string对象中字符的操作
string对象常见字符处理函数,这些函数都在cctype头文件中定义(即要使用这些函数,必须添加#include<cctype>这个头文件)
表5-2 cctype定义的函数
程序清单—05
#include <iostream> #include <string> //标准库string类型头文件 #include <cctype> //string对象中字符的处理函数的头文件 using std::string; //string类型的using声明 using std::cin; using std::cout; using std::endl; int main() { cout << "string对象中字符的处理" << endl; string testStr("abCHIjk4329#$%~!!! "); cout << testStr << endl; string::size_type alnum_cnt(0); //统计字母或数字的个数 string::size_type alpha_cnt(0); //统计字母的个数 string::size_type digit_cnt(0); //统计数字的个数 string::size_type print_cnt(0); //统计可打印字符的个数 string::size_type graph_cnt(0); //统计除空格外可打印的字符的个数 string::size_type space_cnt(0); //统计空白字符的个数 string::size_type lower_cnt(0); //统计小写字母的个数 string::size_type upper_cnt(0); //统计大写字母的个数 string::size_type punct_cnt(0); //统计标点符号的个数 string::size_type cntrl_cnt(0); //统计控制字符的个数 string::size_type xdigit_cnt(0); //统计十六进制数的个数 cout << "testStr的字符个数:" << testStr.size() << endl; for(string::size_type index=0; index!=testStr.size(); ++index) { if(isalnum(testStr[index])) ++alnum_cnt; if(isalpha(testStr[index])) ++alpha_cnt; if(isdigit(testStr[index])) ++digit_cnt; if(isprint(testStr[index])) ++print_cnt; if(isgraph(testStr[index])) ++graph_cnt; if(isspace(testStr[index])) ++space_cnt; if(islower(testStr[index])) ++lower_cnt; if(isupper(testStr[index])) ++upper_cnt; if(ispunct(testStr[index])) ++punct_cnt; if(iscntrl(testStr[index])) ++cntrl_cnt; if(isxdigit(testStr[index])) { cout << testStr[index] << endl; ++xdigit_cnt; } } cout << "alnum_cnt: " << alnum_cnt << endl; cout << "alpha_cnt: " << alpha_cnt << endl; cout << "digit_cnt: " << digit_cnt << endl; cout << "print_cnt: " << print_cnt << endl; cout << "graph_cnt: " << graph_cnt << endl; cout << "space_cnt: " << space_cnt << endl; cout << "lower_cnt: " << lower_cnt << endl; cout << "upper_cnt: " << upper_cnt << endl; cout << "punct_cnt: " << punct_cnt << endl; cout << "cntrl_cnt: " << cntrl_cnt << endl; cout << "xdigit_cnt: " << xdigit_cnt << endl; for(string::size_type index=0; index != testStr.size(); ++index) testStr[index] = tolower(testStr[index]); cout << "tolower: " << testStr << endl; for(string::size_type index=0; index != testStr.size(); ++index) testStr[index] = toupper(testStr[index]); cout << "toupper: " << testStr << endl; cout << "**************************************** " << endl; system("pause"); return 0; }
程序结果: