标准库类型string
string表示可变长的字符序列,使用string类型必须首先包含string头文件。
文章目录
- 一、定义和初始化string对象
- 二、操作string对象
- 三、处理string对象中的字符
一、定义和初始化string对象
如何初始化类的对象是由类本身决定的。
1.拷贝初始化:
使用=
初始化一个变量,编译器把等号右侧的初始值拷贝到新创建的对象中去。
2.直接初始化:不使用=
string s1;//s1是一个空串,该string对象中没有任何字符。
string s2(s1);
string s2 = s1;
string s3("value");
string s3 = "value";//这个字符串字面值,除了最后那个空字符以外,全部被拷贝到新建的s3对象中去。
string s4(n,'c');//string s4(6,'c');把s4初始化成,连续6个字符c组成的串。
二、操作string对象
类除了规定初始化其对象,还能够定义对象上能执行的方法。
类既可以通过函数名调用方法,也可以定义<<、+等各种运算符在该类对象上的新含义。
1.读写 string 对象
在使用cin执行读取操作时,string对象会忽略开头空白,从第一个字符开始,到下一个空白结束。
#include<iostream>
#include<string>
using namespace std;
int main(){string s;cin>>s;cout<<s<<endl;return 0;
}
//输入: hello world
//输出:hello
2.读取未知数量的 string 对象
string word;
while(cin >> word)//没遇到文件结束标记或者非法输入,一直读取cout << word << endl;
3.使用 getline 读取一整行
如果说在最终字符串中保留输入时的空白,使用getline函数替代>>。
函数从给定的输入流中读取数据,直到遇到换行符为止(换行符也被读进来了),然后把所读的内容存放在string对象里(这里面不存在换行符)。
如果输入一开始就是个换行符,那么所得结果是一个空string。
string line;
getline(cin, line);
cout << line << endl;
//getline返回它的流参数,我们也能把getline的结果作为条件。
while(getline(cin, line))//每次读一整行,直到文件末尾。cout << line << endl;
4.string 的 empty 和 size 操作:
empty是string的一个成员函数,使用点操作符指明是那个对象执行了 empty 函数即可。
s.empty()
s为空返回true,否则返回false。
while (getline(cin, line))//只输出非空的行if(!line.empty())//如果line不为空则返回真。cout << line << endl;
size函数返回string对象的长度(字符的个数)。
while (getline(cin, line))//只输出超过80个字符的行if(line.size() > 80)cout << line << endl;
size函数返回的是string::size_type类型的值,它是一个无符号类型的值,而且能够存放下任何string对象的大小。
string s;
cin>>s;
auto len = s.size();//c++11允许通过auto来推断变量类型
cout << len;
5.字符串字面值和string是不同的类型。
使用+运算符,必须确保每个+的两侧的运算对象至少有一个是string。
//字面值和string对象相加:
string s4 = s1 + ",";//正确
string s5 = "hello" + ",";//错误
string s6 = (s1 + ",") + "world";//正确,对string对象使用+运算符得到一个新的string对象。
三、处理string对象中的字符
1.使用 范围for(range for)语句处理每个字符
范围for语句:遍历给定序列中的每个元素并对序列中的每个值执行某种操作。
//语法形式:
for (declaration : experssion)statement
/*
experssion: 一个对象,用于表示一个序列。
declaration: 定义一个变量,该变量用于访问序列中的基础元素。
statement: 对每个元素的操作。
*/
string str("some words");
for (auto c : str)//对于str中的每一个字符。每次迭代,str的下一个字符被拷贝给c。cout << c << endl;//输出当前字符并加一个换行符。
改变某个字符的特性,利用cctype头文件中的函数,进行相应判断:
isdigit(c);//c是数字时为真。
isalpha(c);//c是字母时为真。
ispunct(c);//c是标点符号时为真,即c不是控制字符、数字、字母、可打印空白中的一种。
toupper(c);//如果c是小写字母,输出对应的大写字母,否则原样输出c。
...
//还有很多,请查手册。
string s("HELLO WORLD!!!");
decltype(s.size()) punct_cnt = 0;//punct_cnt类型和s.size类型相同。
for (auto c : s)if (ispunct(c))//对于s中每个字符,如果该字符是标点符号,将标点符号计数值加一。++punct_cnt;
cout << punct_cnt<< " punctuation characters in " << s << endl;
2.使用 范围for 语句改变字符串中的字符
把循环变量定义成引用类型即可,使用引用作为循环控制变量时,这个变量被依次绑定到了序列的每个元素上。
string s("Hello World!!");
for(auto &c : s)c = toupper(c);//c是一个引用,因此赋值语句将改变s中字符的值。
cout << s << endl;//输出:HELLO WORLD
3.只处理一部分字符
访问string 对象的单个字符有两种方式,一种是用下标,另一种是用迭代器。这里先介绍通过下标的方法。
- string对象的下标必须>=0 而且 <s.size()。
- 如果下标是带符号类型的值,将自动转换成由 string::size_type 表达的无符号类型。
- 下标运算符[]接收的输入参数是 string::size_type 类型的值,这个参数表示要访问的字符的位置,返回值是该位置上字符的引用。
- 不管什么时候只要对string对象使用了下标,都要确认在那个位置上确实有值。
if (!s.empty())//在访问指定字符之前,首先检查s是否为空。如果s为空,则s[0]的结果将是未定义的。cout << s[0] << endl;string s("some string");
if (!s.empty())s[0] = toupper(s[0]);//将字符串首字母变成大写。
//只要字符串不是常量,就能为下标运算符返回的字符赋新值。
4.使用下标执行迭代:
for (decltype(s.size()) index = 0;index !=s.size() && != isspace(s[index]); ++index)s[index] = toupper(s[index]);
//依次处理s中的字符,直至我们处理完全部字符或者遇到一个空白
//如果s是some thing,经过操作,s变成SOME thing
这里使用了:index !=s.size() && != isspace(s[index])
c++语言规定,只有左侧运算对象为真,才会检查右侧运算对象。因此只有在index达到s.size()之前,才会执行s[index],这样确保index比s.size()小。