标准库类型string表示可变长的字符序列。使用string需包含stringt头文件,定义在命名空间std中。
初始化string对象的方式
string s1;
默认初始化,s1是一个空串;
string s2(s1);
直接初始化,s2是s1的副本;
string s2 = s1; 拷贝初始化,等价于s2(s1);
string s3("value");
直接初始化,s3是字面值“value"的副本,除了字面值最后的那个空字符外;
string s3 = "value";
拷贝初始化,等价于s3(“value”);
string s4(n, 'c');
直接初始化,把s4初始化为由连续n个字符c组成的串;
string s5 = string(10, 'c');
拷贝初始化,s5内容为cccccccccc,等价于
string tmp(10, 'c'); string s5 = temp;
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;
如果s1和s2中所含的字符完全一样,则它们相等;string对象的相等性判断对字母的大小写敏感
<, <=, >, >=;
利用字符在字典中的顺序进行比较,且对字母的大小写敏感
#include<iostream>
using std::cin;
using std::cout;
using std::endl;
using std::string;
int main()
{
string s; //空字符串
cin >> s; //将string对象读入s,遇到空白停止
cout << s << endl; //输出s
return 0;
}
在执行读取操作时,string对象会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇见下一处空白为止。
输入" hello world ";输出 “hello”
string s1, s2;
cin >> s1 >> s2; //把第一个输入读到s1中,第二读入s2
cout << s1 << s2 << endl; //输出两个string对象
输入" hello world ";输出 “helloworld”
读取未知数量的string对象
int main()
{
string word;
while(cin >> word) //反复读取,直至到达文件末尾
{
cout << word << endl; //逐个输出单词,每个单词后面跟1个换行
}
return 0;
}
使用getline读取一整行内容
int main()
{
string line;
//每次读入一整行,遇到空行跳过
//输出其中不超过60个字符的行,直至到达文件末尾
while(getline(cin, line))
{
if(!line.empty && line.size() < 60)
{
cout << line << endl;
}
}
return 0;
}
触发getline函数返回的那个换行符被丢弃了,得到的string对象中并不包含该换行符
假设n是一个具有负值的int,则表达式s.size()<n的判断结果几乎肯定是true。因为负值n会自动地转换成一个比较大的无符号值。
比较string对象
==、!=、<, <=, >, >=运算符依照(大小写敏感的)字典顺序:
1、如果两个string对象的长度不同,而且较短string对象的每个字符都与较长string对象对应位置上的字符相同,就说较短string对象小于较长string对象。
2、如果两个string对象在某些对应的位置上不一致,则string对象比较的结果是string对象中第一对相异字符比较的结果。
eg:
string s1 = "code test";
string s2 = "code";
string s3 = "copy";
根据规则1,s1>s2;根据规则2,s3>s1>s2;
处理string对象中的字符
如果想对string对象中的每个字符做一些操作,可以使用C++11新标准提供的一种语句:范围for(range for)语句,可遍历给定序列中的每个元素并对序列中的每个值执行某种操作,语法形式为:
for (declaration : expression)
statement
其中,expression部分是一个对象,用于表示一个序列。declaration部分负责定义一个变量,该变量将被用于访问序列中的基础元素;每次迭代,declaration部分的变量会被初始化为expression部分的下一个元素值。
//使用范围for语句和ispunct函数
//来统计string对象中标点符号的个数
string s("Hello World!!1");
//punct_cnt的类型和s.size的返回类型一样
decltype(s.size()) punct_cnt = 0;
//统计s中标点符号的数量
for(auto c : s) //对于s中的每个字符
if(ispunct(c))
++punct_cnt;
cout << punct_cnt << "punctuation characters in " << s << endl;
结果:2 punctuation characters in Hello World!!1
要改变string 对象中字符的值,要把循环变量定义成引用类型;当使用引用作为循环控制变量时,这个变量被依次绑定到了序列的每个元素上;使用这个引用可以改变它绑定的字符。
//字符串中字母转换为大写
string s("Good morning!");
for(auto &c : s) //对于s中的每个字符
c = toupper(c); //c是一个引用,赋值语句将改变s中字符的值
cout << s << endl;
输出:GOOD MORNING!
//将字符串的首字符改成大写
string s("good luck!");
if(!s.empty()) //确保s[0]位置确实有字符
s[0] = toupper(s[0]); //s的第一个字符赋新值
cout << s << endl;
输出:Good luck!
//字符串中第一个词改为大写
string s("good luck!");
//依次处理s中字符至处理完全部字符或遇到空白
for(decltype(s.size()) index = 0;
index != s.size() && !isspace(s[index]); index++)
s[index] = toupper(s[index]);
cout << s << endl;
输出:GOOD luck!