部分内容摘抄自http://t.csdnimg.cn/BM0jO
目录
温故:C库函数中和字符串有联系的函数
知新:C++ string常见用法
string的初始化
1.常见初始化方式
string对象的操作
1.用cin获取键盘输入的值
2.用getline读取一整行
3.string对象相加
3.1 两个string相加
3.2 string对象加上一个字符(或字符串)字面值
如何获取和处理string中的每个字符
1.使用下标运算符[](最省事)
2.使用迭代器
3.使用基于范围的for语句
4.使用at方法获取字符
string类的成员函数
string赋值操作assign()
string字符串拼接+=,append
string查找和替换find,rfind,replace
string字符串比较compare
string插入和删除insert,erase
string子串截取substr
string字符数字转整型数字操作stoi,stol,stoll
string字符数字转浮点型数字操作stof,stod,stold
string数字转字符操作to_string
string字符大小写转换
练手习题
“简单题”
最后的元音 【参考代码】
标题统计 【参考代码】
奇怪的数列 【参考代码】
“中等题”
FBI树 【参考代码】
“中等+题”
串的处理 【参考代码】
温故:C库函数中和字符串有联系的函数
#include <string.h>
C++使用 <cstring>
string.h头文件在C语言标准库中提供了一组用于处理字符串的函数。以下是一些主要的函数:
- strlen:计算字符串的长度,不包括空结束字符。
- strcpy:复制字符串。
- strcmp: 比较字符串大小
- strncpy:复制指定数量的字符。
- memset:将某块内存中的每个字节设置为指定值。
#include <stdio.h>
#include <string.h>int main()
{char s[] = "hello";printf("%d\n", strlen(s)); //输出字符数组s的大小char s1[10]; strcpy(s1, s); //将s数组copy到s1数组for(int i=0; s1[i] != '\0'; i++)printf("%c", s1[i]);printf("\n"); char s2[10];strncpy(s2, s1, 3); //提取s1中前面3个字符到s2for(int i=0; s2[i] != '\0'; i++)printf("%c", s2[i]);printf("\n");char s3[] = "hello world";char s4[] = "hello";char s5[] = "he";if(strcmp(s3, s1) > 0)printf("s3大于s1\n");else if(strcmp(s3, s1) == 0)printf("s3等于s1\n");elseprintf("s3小于s1\n");if(strcmp(s4, s1) > 0)printf("s4大于s1\n");else if(strcmp(s4, s1) == 0)printf("s4等于s1\n");elseprintf("s4小于s1\n");if(strcmp(s5, s1) > 0)printf("s5大于s1\n");else if(strcmp(s5, s1) == 0)printf("s5等于s1\n");elseprintf("s5小于s1\n");int a[5] = {1, 1, 1, 1, 1};memset(a, 0, sizeof(a));for(int i=0; i<5; i++)printf("%d ", a[i]);return 0;
}
输出:
知新:C++ string常见用法
string的初始化
1.常见初始化方式
string对象的初始化和普通类型变量的初始化基本相同,只是string作为类,还有类的一些特性:使用构造函数初始化。如下表,第2 4 6条是作为类才有的初始化方式:
当然,也可以用下面这种格式初始化,其实就是调用string的构造函数生成一个临时的string类,再用临时的string类初始化s5 s6。
string s5 = string("value");
string s6(string("value"));
区别初始化和赋值操作:
区别其实很简单,初始化是生成对象的时候(也就是刚分配内存空间时)就给它值;赋值就是过了初始化后,给对象值。下面的例子就是给st1赋值:
string st1, st2(3,'b');
st1 = st2; //st1此时已近占据了一块内存
cout << st1 << endl;
cout << st2 << endl;
输出:
string对象的操作
1.用cin获取键盘输入的值
用法很简单,和int、double等内置类型的cin一样使用。不过需要说明一点:
string对象会自动忽略开头的空白(既空格、换行符、制表符等),并从第一个真正的字符开始读入,直到遇到下一处空白
看下面的示例:
string s1;
cin >> s1;
cout << s1 << endl;
忽略了输入Hello world前的空白。从H开始读取字符,在o后面遇到了一处空白,此时不再读取后面的字符。注意,world其实还在缓冲区内,如果再用cin读取,你无法从键盘输入,会直接读到world。
输出:
2.用getline读取一整行
getline的函数格式:getline(cin,string对象);
getline的作用是读取一整行,直到遇到换行符才停止读取,期间能读取像空格、Tab等的空白符。实例如下:
string s1;
getline(cin, s1);
cout << s1 << endl;
输出:
注意:getline函数和cin一样,也会返回它的流参数,也就是cin,所以可以用getline循环读取一行:
3.string对象相加
3.1 两个string相加
string str = "Hello,";string phrase = "world!";string s = str + phrase; //新建一个字符串cout << s << endl;str += phrase;//相当于str = str + phrasecout << str << endl;
输出:
3.2 string对象加上一个字符(或字符串)字面值
首先问一个问题:为什么string对象可以加上字符或字符串字面值?实际上是因为它们可以自动转换为string类型。下面看例子:
string str = "Hello";
string phrase = "world";string s = str + '!'+ phrase;
cout << s << endl;
输出:
判断下面的加法是否正确?
string str = "Hello";
(1)string s2 = str + "," + "world";
(2)string s3 = "Hello" + "," + str;
答案:(1)正确;(2)错误
(2)错误的原因是:当string对象和字符或字符串字面值相加时,必须确保+号的两侧的运算对象至少有一个string。
至于(1),需要明白,str + “,”会返回一个string类。
如何获取和处理string中的每个字符
1.使用下标运算符[](最省事)
当成数组来用就行
2.使用迭代器
string s = "Hello world!";
for (auto i = s.begin(); i != s.end(); i++)
{cout << *i << ",";
}
cout << endl;
输出:
3.使用基于范围的for语句
基于范围的for语句是C++11新提供的一种语句,其语法形式是:
declaration:定义一个变量,它每次的值都是expression中的基础元素
expression:一个已经定义的对象(变量)
statement:具体的语句
这样看上去还不明白的话,请看下面的例子,通过例子就可以很好理解:
string str("some string");
for (auto c : str)cout << c << ",";
cout << endl;
c就是declaration;str就是expression;cout << c << “,”;就是statement。
for循环把c和str联系起来了。此例中,通过auto关键字让编译器推断c的类型,c这里的类型实际上推断出的是char类型,c每次的值都是str中的一个字符,上述代码的运行的结果如下:
当你需要修改
str
中的字符时,你可以使用引用,既:
for (auto &c : str)
。
--------------------------------------------------
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43744293/article/details/118299233
4.使用at方法获取字符
#include<iostream>
#include<string>
using namespace std;//string字符存取
void test01()
{string str1 = "hello";//通过at方式访问的单个字符for (int i = 0; i < str1.size(); i++){cout << str1.at(i) << " ";}cout << endl;//修改单个字符str1.at(0) = 'x';cout << str1 << endl;
}
int main()
{test01();return 0;
}
输出:
string类的成员函数
string赋值操作assign()
功能描述:给string字符串进行赋值
赋值的函数原型:
- string& operator = (const char* s)char*类型字符串赋值给当前的字符串
- string& operator = (const string &s)把字符串s赋给当前的字符串
- string& operator = (char c)把字符赋值给当前的字符串
以上都是重载运算符
- string& assign(const char* s)把字符串s赋值给当前的字符串
- string& assign(const char*s,int n)把字符串s的当前n个字符赋给当前的字符串
- string& assign(const string &s)把字符串s赋给当前字符串
- string& assign(int n,char c)用n个字符c赋给当前字符串
#include<iostream>
#include<string>
using namespace std;void test01()
{string str1;str1 = "hello world";cout << "str1=" << str1 << endl;string str2;str2 = str1;cout << "str2=" << str2 << endl;string str3;str3 = 'c';cout << "str3=" << str3 << endl;string str4;str4.assign("hello c!");cout << "str4=" << str4 << endl;string str5;str5.assign("hello c++",5);cout << "str5=" << str5 << endl;string str6;str6.assign(str5);cout << "str6=" << str6 << endl;string str7;str7.assign(10, 'w');cout << "str7=" << str7 << endl;
}
int main()
{test01();return 0;
}
输出:
总结:string赋值方式很多,operator=这种方式是比较实用的。
string字符串拼接+=,append
功能描述:实现在字符串末尾拼接字符串
函数原型:
- string& operator+=(const char* str)重载+=操作符,在字符串后面加char*类型的字符数组
- string& operator+=(const char c)重载+=操作符,在字符串后面加一个字符
- string& operator+=(const string& str)重载+=操作符,在字符串后面加一个string对象
以上都是重载运算符
- string& append(const char* s)把字符串s连接到当前字符串结尾
- string& append(const char* s,int n)把字符串s的前n个字符连接到当前字符串的结尾
- string& append(const string &s)同operator+=(const string& str)
- string& append(const string &s,int pos,int n)把字符串s中从pos开始的n个字符连接到字符串结尾
#include<iostream>
#include<string>
using namespace std;void test01()
{string str1 = "You ";str1 += "are gay"; //在str1后面加字符串cout << "str1=" << str1<< endl;str1 += '?'; //加字符cout << "str1=" << str1 << endl;string str2 = "zbc";str1 += str2; //在str1后面加string对象cout << "str1=" << str1 << endl;string str3 = "You";str3.append(" SB"); //使用append函数cout << "str3=" << str3 << endl;str3.append("hahaha yayaya", 4); //在append函数中的字符串取前4个字符加入str3cout << "str3=" << str3 << endl;str3.append(str2); //在末尾添加字符串cout << "str3=" << str3 << endl;str3.append(str2, 0, 1); //在str2中从0开始的1个字符(‘z’)连接到字符串结尾cout << "str3=" << str3 << endl;
}
int main()
{test01();return 0;
}
输出:
总结:字符串拼接的重载版本很多,初学阶段熟练使用其中几种即可。
string查找和替换find,rfind,replace
功能描述:
- 查找:查找指定位置字符串是否存在
- 替换:在指定的位置替换字符串
函数原型:
#include <iostream>
#include <string>
using namespace std;//字符串的查找
void test01()
{string str1 = "abcdefg";//找到返回下标,找不到返回-1int pos1 = str1.find("de"); //从左到右int pos2 = str1.rfind("de"); //从右往左cout << "pos1=" << pos1 << endl;cout << "pos2=" << pos2 << endl; pos2 = str1.find("z");cout << "pos2=" << pos2 << endl; //返回-1
}//字符串的替换
void test02()
{string str2 = "abcdef";str2.replace(1, 3, "11111111"); //从1号位置到3号位置替换为字符串"11111111",其余不变cout << "str2=" << str2 << endl;
}int main()
{test01();test02();return 0;
}
总结:
- find查找是从左往右,rfind从右往左(reversefind)
- find找到字符串后返回查找的第一个字符位置,找不到返回-1
- replace在替换时,要指定从哪个位置起,多少个字符,替换成什么样的字符串
string字符串比较compare
功能描述:字符串之间的比较
比较方式:
字符串比较是按字符的ASCII码进行对比,=时返回0,>时返回1,<时返回-1
函数原型:
- int compare (const basic_string& s) const;
- int compare (const Ch* p) const;
- int compare (size_type pos, size_type n, const basic_string& s) const;
- int compare (size_type pos, size_type n, const basic_string& s,size_type pos2, size_type n2) const;
- int compare (size_type pos, size_type n, const Ch* p, size_type = npos) const;
#include<iostream>
#include<string>
using namespace std;//字符串比较
void test01()
{string str1 = "zello";string str2 = "hello";if (str1.compare(str2) == 0){cout << "相等" << endl;}else if (str1.compare(str2) > 0){cout << "str1大" << endl;}else{cout << "str2大" << endl;}
}
int main(void)
{test01();system("pause");return 0;
}
总结:字符串对比主要是用于比较两个字符串是否相等,判断谁大谁小的意义并不是很大。
string插入和删除insert,erase
功能描述:对string字符串进行插入和删除字符操作。
函数原型:
#include<iostream>
#include<string>
using namespace std;
//字符串插入和删除
void test01()
{string str = "hello";//插入str.insert(1, "111");cout << "str = " << str << endl;//删除111str.erase(1,3);cout << "str = " << str << endl;
}
int main(void)
{test01();return 0;
}
输出:
总结:插入和删除的起始下标都是从0开始。
string子串截取substr
功能描述:从字符串中获得想要的子串。
函数原型:
string substr(int pos = 0, int n = npos) const; //返回由pos开始的n个字符组成的字符串。如果只有一个参数,截取范围即为该参数的位置至字符串末尾
#include<iostream>
#include<string>
using namespace std;//string求子串
void test01()
{string str = "abcdef";string subStr = str.substr(1, 3); //截取下标从1-3的字符(下标从0开始)cout << "subStr=" << subStr << endl;
}
//使用操作
void test02()
{string email = "zhangsan@qq.com";//从邮箱地址中获取用户名信息int pos = email.find("@"); //找到@字符的位置string usrName = email.substr(0, pos); //截取“zhangsan”cout << usrName << endl;
}
int main(void)
{test01();test02();return 0;
}
输出:
总结:灵活的运用求子串功能,可以在实际开发中获取有效的信息。
string字符数字转整型数字操作stoi,stol,stoll
stoi是String TO Int的英文缩写,stol就是String TO Long, stoll就是string to long long
注:base是进制的意思
用于将字符数字转成整型数字,如:’1’ 变成 1。函数形参传入string类型的地址
#include <iostream>
#include <string>
using namespace std;int main()
{string s1 = "3.14";cout << stoi(s1) << endl;string s2 = "3.14 circle 11";cout << stoi(s2) << endl;string s3 = "999999999999999";cout << stoll(s3) << endl;string s4 = "2023";int newyear = stoi(s4); //转int型cout << ++newyear << endl; //加1操作string s5 = "c 3.14"; //错误示范,字符串开始不能有字母cout << stoi(s5) << endl;string s5 = "c 3.14"; cout << stof(&s5[2]) << endl; //正确示范,输出3.14return 0;
}
输出:
总结:字符串中混杂着字母和数字时,还是用下标运算符来做更方便。
string字符数字转浮点型数字操作stof,stod,stold
stof是String TO Float的英文缩写,stod就是String TO Double, stold就是string to long double
#include <iostream>
#include <string>
using namespace std;int main()
{string s1 = "3.14";cout << stof(s1) << endl;string s2 = "3.14444444444444444";cout << stod(s2) << endl;string s3 = "3.14444444444444444";cout << stold(s3) << endl;return 0;
}
输出:
string数字转字符操作to_string
#include <iostream>
#include <string>
using namespace std;int main()
{int value1 = 2024;string s1 = to_string(value1);cout << s1 << endl;float value2 = 3.14;string s2 = to_string(value2);cout << s2 << endl;long long value3 = 1e18;string s3 = to_string(value3);cout << s3 << endl; //18个0return 0;
}
输出:
string字符大小写转换
定义于头文件 <cctype>
int tolower( int ch );
int toupper( int ch );
该函数只能一个一个字符进行转换,只对字母有效,对数字无效
#include <iostream>
#include <string>
#include <cctype>
using namespace std;int main()
{string s1 = "aaBBcc666";for(int i=0;i<s1.size();i++){s1[i] = toupper(s1[i]);}cout << s1 << endl;string s2 = "aaBBcc666";for(int i=0;i<s2.size();i++){s2[i] = tolower(s2[i]); //改了BB}cout << s2 << endl;return 0;
}
输出:
练手习题
“简单题”
最后的元音
题目链接
【参考代码】
主要考察使用下标运算符获取string中每个字符
#include <iostream>
#include <string>
using namespace std;int main()
{// 请在此输入您的代码string s;cin>>s;for(int i=s.size()-1;i>=0;i--){if(s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u'){cout << s[i] << endl;return 0; //结束程序}}
}
标题统计
题目链接
【参考代码】
主要考察getline()、size()、使用下标运算符获取string中每个字符
#include <iostream>
#include <string>
using namespace std;
int main()
{// 请在此输入您的代码string s;getline(cin,s); //读取一行字符串,包括空格。tips:cin输入流遇到空格就停止了int n = s.size();int count=0;for(int i=0;i<n;i++){if(s[i] == '\n' || s[i] == ' ') //不含空格和换行符continue;elsecount++;}cout << count;return 0;
}
奇怪的数列
题目链接
【参考代码】
主要考察使用下标运算符获取string中每个字符,to_string()函数的使用
#include <iostream>
#include <string>
using namespace std;
int main()
{// 请在此输入您的代码string s1;string s2 = "";int n;cin>>s1;cin>>n;for(int i=0;i<n;i++){int cnt = 1;for(int j=0;j<s1.size();j++){if(s1[j] == s1[j+1])cnt++;else{s2 += to_string(cnt);s2 += s1[j];cnt = 1;}}s1 = s2;s2 = "";}cout << s1;return 0;
}
“中等题”
下面这题需要学习二叉树相关知识才能做
FBI树
题目链接
【参考代码】
主要考察size()、find()、substr()使用
#include <iostream>
#include <string>
using namespace std;struct node{char data;int leftson, rightson;
}tree[1000000];void lastorder(int p)
{if(p != 0){lastorder(tree[p].leftson);lastorder(tree[p].rightson);cout << tree[p].data;}
}void function(string s, int dot)
{int size = s.size();bool flag1 = false, flag0 = false;if(s.find('1') != -1) //等于-1就是找不到{flag1 = true;}if(s.find('0') != -1) //等于-1就是找不到{flag0 = true;}if(flag0 == true && flag1 == true)tree[dot].data = 'F';else if(flag0 == true && flag1 == false)tree[dot].data = 'B';else if(flag0 == false && flag1 == true) //可不写tree[dot].data = 'I';if(s.size() == 1) //结束条件。放开头不行,叶子结点未赋值return;tree[dot].leftson = dot*2; //给伪指针赋值tree[dot].rightson = dot*2+1;int mid = size/2;function(s.substr(0, mid), tree[dot].leftson); //左孩子function(s.substr(mid, size), tree[dot].rightson); //右孩子
}int main()
{// 请在此输入您的代码int n;string s;cin>>n;cin>>s;function(s, 1);lastorder(1);return 0;
}
“中等+题”
串的处理
题目链接
【参考代码】
#include <iostream>
#include <string>
using namespace std;int main()
{// 请在此输入您的代码string s;getline(cin,s);int n = s.size();for(int i=0;i<n;i++){//排除空格后是数字的情况,空格后是字母才要变大写if( (i==0 || s[i-1] == ' ') && (s[i] >= 'a' && s[i] <= 'z') )s[i] = s[i] - 32;//字母在前,数字在后的情况if( ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) && (s[i+1] >= '0' && s[i+1] <= '9') ){s.insert(i+1,"_"); //string常用的成员函数insert(), append()continue;}//数字在前,字母在后的情况if( ((s[i+1] >= 'a' && s[i+1] <= 'z') || (s[i+1] >= 'A' && s[i+1] <= 'Z')) && (s[i] >= '0' && s[i] <= '9') ){s.insert(i+1,"_"); //在i+1的位置插入_continue;}if(s[i] == ' ' && s[i+1] == ' '){s.erase(i,1); //删除第i位置上的一个字符--i; //删除之后,所有字符会向前移动一位,自动i+1,需要后退一步}}cout << s;return 0;
}