• C++ 字符串


    C++ 提供的字符串形式:

    • C 风格字符串
    • C++ 引入的 string 类类型

    C 风格字符串

    起源:C 语言

    实质:使用 null 字符 \0终止的一维字符数组。一个以 null 结尾的字符串,包含了组成字符串的字符。

    char site[5]={'y','u','y','a','\0'};//字符数组的大小比 yuya 的字符数多一个

    char site[5]="yuya";

    不需要把 null 字符放在字符串常量末尾,因为 C++ 编译器会在初始化数组时,自动把\0放在字符串的末尾

    String 类

    头文件:string,使用时必须包含

    string 定义在命名空间 std 中

    #include

    using std::string;

    初始化

    string s1; 默认初始化,s1 是一个空字符串

    string s2(s1); s2 是 s1 的副本

    string s2=s1; 等价于 s2(s1),s2 是 s1 的副本

    string s3("yuya"); s3 是字面值 "yuya" 的副本,除了字面值最后的那个空字符外

    string s3="yuya"; 等价于 s3("yuya"),s3 是字面值 "yuya" 的副本

    string s4(n,'c'); 把 s4 初始化为由连续 n 个字符 c 组成的串

    操作

    os< 将 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+1 个字符的引用,位置 n 从 0 计起

    s1+s2 返回 s1 和 s2 连接后的结果

    s1=s2 用 s2 的副本代替 s1 中原来的字符

    s1==s2 如果 s1 和 s2 中所含的字符完全一样,则它们相等;string 对象的相等性判断对字母的大小写不敏感

    s1!=s2

    <,<=,>,>= 利用字符在字典中的顺序进行比较,且对字母的大小写不敏感

    读写

    1. >>、<<
    2. getline

    string s;

    cin>>s;

    cout<

    执行读取操作时,string 对象会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇见下一处空白为止

    读取未知数量的 string 对象

    while(cin>>word) 反复读取,直至到达文件末尾

    cout<

    重复若干次之后,一旦遇到文件结束标记或非法输入循环结束

    getline

    使用 getline 代替 >> ,可以在最终得到的字符串中保留输入时的空白符

    参数:一个输入流,一个 string 对象

    函数从给定的输入流中读入内容,直到遇到换行符为止,此时,换行符也被读进来,把所读的内容存入到 string 对象中,此时不存换行符。getline 只要遇到换行符就结束读取操作并返回结果,哪怕是一开始就是换行符也是如此,此时所得的结果是空 string【触发 getline 函数返回的换行符实际上被丢弃了,得到的 string 对象不包含该换行符】

    getline 也会返回其参数流,故可以作为判断条件

    string line;

    while(getline(cin,line))

    cout<

    判断字符串是否为空

    empty

    empty 函数根据 string 对象是否为空返回一个对应的布尔值

    string line;

    while(getline(cin,line))

    if(!line.empty()) 遇到空行直接跳过

    cout<

    长度

    1. size
    2. length
    size

    size 函数返回 string 对象的长度,即 string 对象中字符的个数

    string line;

    while(getline(cin,line))

    if(line.size()>80) 只输出字符个数超过80的行

    cout<

    size 函数返回的是一个 string::size_type 类型的值,是一个无符号类型的值,能足够存放下任何 string 对象的大小。C++11 新标准中,允许编译器通过 auto 或者 decltype 推断变量的类型:

    auto len=line.size(); len 的类型是 string::size_type

    size 函数返回一个无符号整型数,在表达式中混用带符号数和无符号数将会产生意想不到的结果,例如:假设 n 是一个具有负值的 int ,则表达式 s.size() 的判断结果几乎肯定是 true,因为负值 n 会自动转化成一个比较大的无符号值【如果一条表达式中已经有了 size() 函数就不要再使用 int ,可以避免混用 int 和 unsigned 可能带来的问题】

    length

    等同于 size

    赋值

    对于 string 对象,允许把一个对象的值赋给另外一个对象

    string st1(10,'c'),st2;

    st1=st2; //将 st2 的值赋给 st1,此时,二者均为空字符串

    清空

    clear

    功能:清空字符串内容,变成一个空字符串

    str.clear();

    删除字符

    erase

    函数原型:string& erase(size_t pos = 0, size_t n = npos);

    iterator erase(iterator position);

    iterator erase(iterator first, iterator last);

    用法:erase(pos, n); //删除从pos开始的n个字符,比如erase(0, 1)就是删除第一个字符

    erase(position); //删除从position处的一个字符(position是个string类型的迭代器)

    erase(first, last); //删除从first到last之间的字符(first和last都是迭代器)

    比较 string 对象

    比较运算符

    比较运算符逐一比较 string 对象中的字符,并且对大小写敏感

    相等性运算符(==和!=)分别检验两个 string 对象相等或不相等,string 对象相等意味着其长度相同并且所包含的字符也全都相同

    关系运算符 <、<=、>、>= 分别检验一个 string 对象是否小于、小于等于、大于、大于等于另外一个 string 对象

    上述运算符都依照(大小写敏感的)字典顺序:

    1. 如果两个 string 对象的长度不同,而且较短 string 对象的每个字符都与较长 string 对象对应位置上的字符相同,则说较短 string 对象小于较长 string 对象
    2. 如果两个 string 对象在某些对应的位置上不一致,则 string 对象比较的结果其实是 string 对象中第一对相异字符字符比较的结果

    string s1="Hello";

    string s2="Hello World";

    string s3="Hiya";

    s3>s2>s1

    compare
    • 两个字符串相同,返回0
    • 调用字符串小于被调用字符串,返回-1
    • 调用字符串大于被调用字符串,返回 1

    s1.compare(s2); //直接比较s1和s2

    s1.compare(pos,n,s2); //s1下标为pos的字符开始的n个字符构成的子串与s2进行比较

    s1.compare(pos,n,s2,pos1,n1); //s1下标为pos的字符开始的n个字符构成的子串与s2下标为pos1的字符开始的n1个字符构成的子串进行比较

    指定位置插入字符串

    insert

    s1.insert(pos,str); //在s1下标为pos的字符前插入字符串str

    s1.insert(pos,str,pos1,n); //str从下标为pos1开始的n个字符插入s1下标为pos的字符前

    s1.insert(pos,n,c); //在s1下标为pos的字符前插入n个字符c

    拼接

    string + string

    两个 string 对象相加得到一个新的 string 对象,其内容是把左侧的运算对象与右侧的运算对象串接而成,前半部分是加号左侧 string 对象所含的字符,后半部分是加号右侧 string 对象所含的字符

    string s1="hello, " , s2="world\n";

    string s3=s1+s2;

    s1+=s2; //等价于s1=s1+s2

    字面值 + string

    因为标准库允许把字符字面值和字符串字面值转换成 string 对象,所以在需要 string 对象的地方可以使用这两种字面值代替

    string s1="hello" , s2="world";

    string s3=s1+", "+s2+'\n';

    当把 string 对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符(+)的两侧的运算对象至少有一个是 string

    string s4=s1+", "; //正确

    string s5="hello"+", "; //错误

    string s6=s1+", "+"world"; //正确,string s6=(s1+", ")+"world"; 子表达式 s1+", " 的结果是一个 string 对象,作为第二个加号运算符的左侧运算对象,与string tmp=s1+", "; s6=tmp+"world"; 等价

    string s7="hello"+", "+s2; //不能把字面值直接相加,string s7=("hello"+", ")+s2;

    字符串字面值与 string 是不同的类型

    字符串末尾添加字符/字符串

    1. 运算符 +、+=
    2. append 添加字符串
    3. puck_back 添加字符

    string s;

    s+='a';

    s.append('a');

    append

    s1.append(s2); //直接添加另外一个完整的字符串

    s1.append(s2,pos,len); //添加s2的以pos为索引、长度为len的子串

    s1.append(s2,n); //添加s2的前n个字符

    s1.append(n,c); //添加n个字符c

    puck_back

    s1.puck_back(c);

    查找子串

    find

    s1.find(str);

    s1.find(str,pos); //寻找从pos开始匹配str的位置

    find_first_of 第一次出现
    find_last_of 最后一次出现
    find_first_not_of

    在第一个字符串中进行查找,返回第一个与指定字符串中任何字符都不匹配的元素的位置

    find_last_not_of
    rfind 逆向查找

    rfind(str,pos); //从pos开始,向前查找符合条件的字符串

    获取子串

    substr

    函数原型:string substr(size_t pos = 0, size_t len = npos) const;

    功能:从字符串中获取想要的子串

    参数:pos 想要获取的子字符串的第一个字符的位置,如果 pos=s.size() ,则返回一个空字符串,如果pos>s.sizr(),报错 【第一个字符的下标从 0 开始】

    len 子串中所包含的字符数

    返回值:目标对象

    访问变量

    1. at 有越界检查,程序异常跳出执行
    2. 下标 无越界检查,下标越界,会取得不可预知的字符
    at

    s.at(i); //i是下标

    替换字符串

    swap

    s1.swap(s2); //交换字符串s1和s2

    replace

    s1.replace(pos,len,s2); //将s1中从pos下标开始的长度为n的子串用s2替换

    处理 string 对象中的字符

    头文件:cctype

    处理每个字符?

    使用基于范围的 for 语句

    如果想要处理 string 对象中的每个字符,最好使用 C++11 新标准提供的 范围 for 语句,遍历给定序列中的每个元素并对序列中的每个值执行某种操作

    语法形式:

    for(declaration:expression)

    statement

    expression 是一个对象,用于表示一个序列

    declaration 定义一个遍历,该变量将被用于访问序列中的基础元素

    每次迭代,declaration 部分的变量会被初始化为 expression 部分的下一个元素值

    string str("some string");

    for(auto c : str)

    cout<

    通过使用 auto 关键字【自动推断变量的类型】让编译器来决定变量 c 的类型,这里 c 的类型是 char

    //统计 string 对象中标点符号的个数

    string s("Hello World!!!");

    decltype(s.size()) punct_cnt=0; //punct_cnt 的类型与 s.size 的类型一样,auto 与 decltype 一样,都可以推断类型

    for(auto c : s )

    if(ispunct(c))

    punct_cnt++;

    cout<

    使用范围 for 语句改变字符串中的字符

    如果想要改变 string 对象中字符的值,必须把循环变量定义成引用类型。所谓引用只是给定对象的一个别名,因此当使用引用作为循环控制变量时,此变量实际上被依次绑定到了序列的每个元素上,使用这个引用,就能改变它绑定的字符

    //转换成大写形式

    string s("Hello World!!!");

    for(auto &c : s) //c 是引用

    c=toupper(c); //c 是一个引用,因此赋值语句将改变 s 中字符的值

    cout<

    只处理一部分字符?

    访问 string 对象中的单个字符的方式:

    1. 使用下标
    2. 使用迭代器
    下标

    下标运算符 [ ] 接收的输入参数是 string::size_type 类型的值,这个参数表示要访问的字符的位置,返回值是该位置上的字符的引用,下标从 0 计起,s[0] 是第一个字符,s[s.size()-1] 是最后一个字符

    string 对象的下标必须大于等于0而小于 s.size()

    任何表达式只要其值是一个整型值就能作为索引,如果索引是带符号类型的值将自动转换成由 string::size_type 表达的无符号类型

    在访问指定字符之前,首先检查 s 是否为空,无论什么时候对 string 对象使用下标,都要确认该位置上确实有值,如果 s 为空,则 s[0] 的结果是未定义的

    只要字符串不是常量,就可以为下标运算符返回的字符赋新值

    string s("some string");

    if(!s.empty())

    s[0]=toupper(s[0]); //为 s 的第一个字符赋一个新值

    使用下标执行迭代

    //把 s 的第一个词改成大写形式

    for(decltype(s.size()) index = 0 ; index != s.size() && !isspace(s[index]) ; ++index)

    s[index]=toupper(s[index]);

    使用下标执行随机访问

    通过计算得到某个下标值,然后直接获取对应位置的字符

    迭代器

    begin 和 end

  • 相关阅读:
    聚醚羰基铑功能化离子液体{[CH3O(CH2CH2O)nmim][Rhx(CO)y]}
    云原生数据库如荼如火,未来可期
    TypeScript对象类型
    R语言-tidyr和dplyr
    DX-11Q信号继电器
    初识设计模式 - 外观模式
    Kotlin 中的 apply 函数详解
    EN 14904运动场地表面—CE认证
    Prometheus PromQL及传统部署 Alertmanager 发送告警
    vue3使用view-ui定制主题
  • 原文地址:https://blog.csdn.net/weixin_65951505/article/details/134229291