一、标准库string类型
1. 头文件
#include <string>
using std::string;
2. 构造函数
string s1; // 默认构造函数,空串
string s2(s1); // 初始化为s1的一个副本
string s3("value"); // 初始化为字符串字面值
string s4(n, 'c'); // 初始化为n个'c'
3. 读取string
cin >> s; // 忽略开头的空格,遇到字符串的第一个空白字符是终止读取
getline(cin, s); // 读取整行文本,直到遇到“换行符”才终止读取,但是字符串中不包含“换行符”
4. 常用操作
s.empty()
s.size()
s[n]
s1 + s2
s1 = s2
v1 == v2 (其他关系运算!=, <, <=, >, >=)
5. 关于string::size_type类型
s.size()返回的是string::size_type类型的值,是string类的配套类型,配套类型可以让库类型的使用与机器无关。
int num = s.size(); // 错误,不能把s.size()的返回值赋给int变量
6. 和字符串字面值的concatenation
+操作符的左右操作数,必须至少有一个是string类型
string s1 = "hello";
string s3 = s1 + ", ";
string s4 = "hello" + ", "; // 错误,试图将两个字符串字面值相加
string s5 = s1 + ", " + "world"; // 正确,因为string类重载了=操作符
特别注意:
string s6 = s1 + "world\n"; // s6的值为"helloworld\n",总共为11个字符,包含最后的换行符
7. 下标操作
s[n] = 'x';
例程如下:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string ss; // 默认构造函数,ss为空串(empty string)
getline(cin, ss); // 读取整行文本,不包括“换行符”
cout << "ss = " << ss << endl;
cout << ss.size() << endl; // 字符个数包括空格在内
cout << "=========================" << endl;
// string常用操作
string s = "hello";
string s1 = s + "world\n"; // 字符串长度包含“换行符”,所以为11个
cout <<"s = " << s << endl;
cout << "s1 = " << s1;
cout << "the size of 's1' is " << s1.size() << endl;
//int a = s1.size(); // 试图将string::size_type类型的值赋给int型变量a,将产生错误
string::size_type a = s1.size(); // 必须定义为string::size_type类型
cout << "the last character is " << s1[a-1];
cout << "the last character is " << s1[10];
cout << "=========================" << endl;
// string类的几个构造函数
string s2(s);
string s3("value s3");
string s4(6,'x'); // 初始化n个重复的字符(不能是字符串)
string s5 = "hallo";
string s6 = "Hfllo";
string s7 = s + ", " + "world";
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;
cout << s7 << endl;
// compare 2 strings
if (s < s5)
cout << s << " is bigger than " << s5 << endl;
else
cout << s5 << " is bigger than " << s <<endl;
if (s < s6)
cout << s << " is bigger than " << s6 << endl;
else
cout << s6 << " is bigger than " << s << endl;
if (ss == s1 )
cout << "ss is equal to s1." << endl;
else
cout << "ss is NOT equal to s1." << endl;
for(string::size_type ix = 0; ix != s1.size(); ++ix)
cout << s1[ix] << " ";
// 下标操作---可以作为左值(被赋值),但必须为字符(不能是字符串)
// 下标索引,从0开始索引
s7[2] = '2'; // 不能是"2"
for(string::size_type ix = 0; ix != s7.size(); ++ix)
cout << s7[ix] << " ";
cout << endl;
cout << "=========================" << endl;
return 0;
}
运行结果:
helloworld
ss = helloworld
10
=========================
s = hello
s1 = helloworld
the size of 's1' is 11
the last character is
the last character is
=========================
hello
value s3
xxxxxx
hello, world
hallo is bigger than hello
Hfllo is bigger than hello
ss is NOT equal to s1.
h e l l o w o r l d
h e 2 l o , w o r l d
=========================
二、标准库vector类型
vector容器内包含了多个同一类型对象,vector是一个类模板,声明时必须指明数据类型。
vector<int> ivec;
vector<string> svec;
1. 头文件
#include <vector>
using std::vector;
2. 构造函数
vector<T> v1; // 默认构造函数,v1为空
vector<T> v2(v1); // 初始化为v1的一个副本
vector<T> v3(n, i); // 包含n个T类型的值i
vector<T> v4(n); // 包含n个默认初始化值
特别注意:如果T类没有提供默认构造函数,那么在初始化时,不仅需要提供元素个数,而且需要提供每个元素的初始化值。
3. 常用操作
v.empty()
v.size()
v.push_back(t) // 在v的末尾增加一个值为t的元素
v[n]
v1 = v2
v1 == v2 (其他关系运算!=, <, <=, >, >=)
4. 关于vector<T>::size_type类型
v.size()返回的是vector<T>::size_type类型的值,是vector类的配套类型,配套类型可以让库类型的使用与机器无关。
int num = v.size(); // 错误,不能把v.size()的返回值赋给int变量
5. 向vector添加元素
string word;
vector<string> txt;
while (cin >> word)
{
txt.push_back(word);
}
6. 下标操作
v[n]可以作为左值,即:可以被赋值。但前提是:v[n]已经存在(容器的size至少为n+1)
vector<int> v;
for(vector<int>::size_type ix = 0; ix !=10; ++ix)
v[ix] = ix; // 错误,v中没有元素,必须先通过push_back()添加
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
int main()
{
vector<int> ivec1;
int x1;
for(vector<int>::size_type ix = 0; ix != 6; ++ix)
{
cin >> x1;
ivec1.push_back(x1);
}
ivec1[5] = 9;
for(vector<int>::size_type ix = 0; ix != ivec1.size(); ++ix)
cout << ivec1[ix] << ',';
cout << endl;
vector<int> ivec2(ivec1);
vector<int> ivec3(8, -3);
vector<float> ivec4(6);
vector<string> svec(10, "hello");
// 迭代器
for(vector<int>::iterator iter = ivec2.begin(); iter != ivec2.end(); ++iter)
cout << *iter << ',';
cout << endl;
for(vector<int>::size_type ix = 0; ix != ivec3.size(); ++ix)
cout << ivec3[ix] << ',';
cout << endl;
for(vector<float>::size_type ix = 0; ix != ivec4.size(); ++ix)
cout << ivec4[ix] << ',';
cout << endl;
for(vector<string>::size_type ix = 0; ix != svec.size(); ++ix)
cout << svec[ix] << ',';
cout<<endl<<endl<<"-----------------------------------------------------"<<endl;
cout<<" The second example: "<<endl;
cout<<"-----------------------------------------------------"<<endl;
char na[][10] = { "abc1", "abc2", "abc3" };
char name[][40] = {"nihao1","nihao2","nihao3"};
vector<char*> vi; //每个元素是: char指针
for (int i = 0; i < 3; i++)
{
cout << "na[" << i << "]=" << na[i] << endl;
cout << "name[" << i << "]=" << name[i] << endl;
}
cout<<"-----------------------------------------------------"<<endl;
for (int i = 0; i < 3; i++)
{
strcat(name[i], na[i]);
vi.push_back(name[i]); //每次添加的是name[i]的地址,由于vector类型是char*
}
cout << "After modification: \n";
for (int i = 0; i < 3; i++)
{
cout << "name[" << i << "]=" << name[i] << endl;
}
cout<<"-----------------------------------------------------"<<endl;
for (int i = 0; i < 3; i++)
{
cout << vi[i] << endl;
}
return 0;
}
运行结果:
1
2
3
4
5
6
1,2,3,4,5,9,
1,2,3,4,5,9,
-3,-3,-3,-3,-3,-3,-3,-3,
0,0,0,0,0,0,
hello,hello,hello,hello,hello,hello,hello,hello,hello,hello,
-----------------------------------------------------
The second example:
-----------------------------------------------------
na[0]=abc1
name[0]=nihao1
na[1]=abc2
name[1]=nihao2
na[2]=abc3
name[2]=nihao3
-----------------------------------------------------
After modification:
name[0]=nihao1abc1
name[1]=nihao2abc2
name[2]=nihao3abc3
-----------------------------------------------------
nihao1abc1
nihao2abc2
nihao3abc3