课程信息01_1. Welcome_哔哩哔哩_bilibili
153集左右
1. 命名和初始化
string str1 ;//kong
string str2 {"friend"};
string planet {"This is moon"};
string str3 {planet};
string str4 {"hello world",4};//用前4个字母 str4
// cout<<str4<<endl; //hell
//这个不知道为什么打印不出来
string str5 {5,'e'};//Yong用重复的char 来初始化string
string str6{"the blue sea",4,3};//从第4个开始,长度为2
cout<<str6<<endl; //blu
2.字符串拼接 concat
cout<<"-----拼接方法1 加号-------"<<endl;
cout<<"----- 加号1-1-------"<<endl;
str1=str2+planet; //str1 是 nameThis is planet
cout<<"----- 加号1-2-------"<<endl;
string str0 {planet+ ','+'O'+str2}; //str0是This is moon,Ofriend;
cout<<str0<<endl;
//注意!!大括号里 有加号,绝对不能直接加字面量常量字符串.
cout<<"----- 加号1-3-------"<<endl;
string str8{string {"comely "} + "lady"};
cout<<str8<<endl;//comely lady
cout<<"------方法2 并排排列------"<<endl;
string str7{"hello" "world"};//中间空格被忽略
cout<<str7<<endl;//helloworld
cout<<"------方法3 s操作符 C++11 ------"<<endl;
//using namespace std::string_literals;
//但是我没鞋上面这句话,居然也行?
string str9 {"bird "s +"kicking"};
cout<<str9<<endl;//bird kicking 但是不写s就报错了!!
string str10="Playing "s+"football";
string str11;
{
str11="find "s+"child";
}
cout<<"------方法4 内置函数append ------"<<endl;
//append了之后,原先的已经改变了!!!
//str12 str14都是一样的 bluelook at the sky
//strA.append(strB),括号里是char *strB, char strB[]也行
string str12{ "blue"};
string str13 {"look at the sky"};
string str14=str12.append(str13);
string str15{ "purple"};
string str16 {str15.append(str13,3,5)};//从3号位置开始 0 12 3 长度为5
//k at
cout<<str16<<endl;//purplek at
string str17{str13.append(5,'X')};
cout<<str17<<endl;//look at the skyXXXXX
3. 数字与字符串之间的转换
3-1. 将数字转换成string ,利用to_string 函数。
cout<<"------其他函数to_string ------"<<endl;
string str18{"Secret"};
// cout<<str18+67<<endl; 报错
str18+=67;
cout<<"不转换,直接相加 "<<str18<<endl;
//SecretC,因为67按照ASC II 码 转换成char 是C
cout<<str18+to_string(67)<<endl;//SecretC67
cout<<13.82f<<endl;//13.82
cout<<to_string(13.82f)<<endl;//13.820000
3-2 将string 转换成数字,有很多函数 ,stoi,stod, stof, stol, stoll, stoull, stold
ld是long double的意思
string nums{"-72.34"};
int int_var=stoi(nums);
double dou_var=stod(nums);
long long_var=stol(nums);
long long ll_var=stoll(nums);
cout<<int_var<<endl;//-72
cout<<dou_var<<endl;//-72.34
cout<<long_var<<endl;//-72
cout<<ll_var<<endl;//-72
4.遍历
cout<<"------字符串遍历 ------"<<endl;
string str19 {"delicious bread"};
for(size_t i{};i<str19.size();i++){
cout<<str19.at(i)<<" ";//str[i]一样
}
cout<<endl;
for(char c:str19){
cout<<c<<" ";
}
cout<<endl;
5.其他函数size() at() front() back()
cout<<"------其他函数size() at() front() back() ------"<<endl;
cout<<"------c_str() method ,返回值不能更改------"<<endl;
string str20 {"The phenoix King"};
const char* wrapped =str20.c_str();
cout<<wrapped<<endl;
cout<<"------data method ,返回值可以改------"<<endl;
//char *wrap2=str20.data();
// cout<<wrap2<<endl;
//不知道怎么报错,看来返回值也是const char*
//但是教学视频里真的能改动,返回是char*
//估计在后面的C++版本里改动了
6.大小 容量
cout<<"------string 大小、容量方面的函数------"<<endl;
//返回整数 str20.size();str20.length();
//整数 str20.capacity()
//返回布尔 str20.empty()
//reserve shrink_to_fit
//clear
//提前保留100个内存位置
str20.reserve(100);
cout<<str20.capacity()<<endl; //从16变成100L
//又一次变回原来的容量了
str20.shrink_to_fit();
cout<<str20.capacity()<<endl;
str20.clear();
//注意!!size=0了 但是容量仍然是原来的16!!
cout<<"size"<<str20.size()<<endl;
cout<<"CC"<<str20.capacity()<<endl;
7.修改
7.1 insert方法
cout<<"------string修改方面的函数-插入 -----"<<endl;
//str.insert(起始pos,插入长度,插入字符)
string str21 {"123456"};
str21.insert(1,3,'A');
cout<<str21<<endl;
//str.insert(起始pos,插入的变量名(类型const char*),插入长度,)
string str22{"Findwater"};
const char *txt {"ABCDEF"};
str22.insert(2,txt,4);
cout<<str22<<endl;//FiABCDndwater
//str.insert(插入开始pos,插入的string常量)
string str23{"--my friend"};
string str24{"Hello!"} ;
str24.insert(5,str23);
cout<<str24<<endl;//Hello--my friend!
//str.insert(插入开始pos,插入的string常量,从常量中开始截取pos,截取长度)
string str25{"ABCDE"};
string str26{"a fox siting on the lawn"} ;
str25.insert(1,str26,6,4);
cout<<str25<<endl;//AsitiBCDE
7.2 erase()方法
//erase(开始位置pos,擦掉长度)
str26.erase(6,str26.size()-6);//str26前面初始化了 "a fox siting on the lawn"
cout<<str26<<endl;//a fox
7.3 push_back()方法
//push_back(char T)
string str27{"hello"};
str27.push_back('!');
cout<<str27<<endl;//hello! //注意别有空格 编译器警告内存溢出
7.4 pop_back()方法
string str28{"tell you"};
str28.pop_back();
cout<<str28<<endl;
8.字符串比较
8.1大于等于小于符号直接比较
//比较 用大于等于号就行 注意 当心不是Null结尾的字符数组.
const char arr[]{'h','e','l','l','o','\0'};
const char arr2[]{'h','e','l','l','o'};
string str29{"hello"};
cout<<(arr==str29)<<endl; //1
cout<<(arr2==str29)<<endl; //0
cout<<(arr2>str29)<<endl; //1
8.2 compare()方法 3种语法
返回值 0 相等,1,前者在 字母表上大于(排在后面) -1 排在前面
//strA.compare(strB)
string str30{"fox"};
string str31{"box"};
cout<<str30.compare(str31)<<endl;
//compare(本字符串比较开始位置,在本字符串上截取长度,给谁比较字符串);
string str32{"the red fox"};
string str33{"fox"};
cout<<str32.compare(8,3,str33)<<endl;
//strA.compare(const char* 或者字面量字符)
const char* message {"class"};
string str34 {"glass"};
cout<<str34.compare(message)<<endl;
cout<<str34.compare("class")<<endl;
9.替换 replace()方法 (往下代码 重新从str1开始编号了)
第一种用法:replace(n1, n2, str)
n1:开始替换位置
n2: 被替换的长度
str:用什么来替换
string str1{"Finding Nemo"};
string str2{"Searching for"};
str1.replace(0,7,str2);
cout<<str1<<endl;//Searching for Nemo
第二种用法: strA.replace(n1,n2,strB,n1,n2)
//strA被strB的部分所替代。
//前两个n1 n2 strA要被替换的位置和长度
//后两个:strB的开始位置和长度
string str3{"Finding Nemo"};
string str4{"We are Searching for food"};
str3.replace(0,7,str4,7,13);
cout<<str3<<endl;//Searching for Nemo
10.copy()方法
strA.copy(dest,n1,n2); 注意长度,字符数组要用null '\0'结尾的。
//dest 接受容器,一个字符数组,必须规定好长度
//n1 接受长度
//n2 从strA的这个位置开始复制
string str5{"ABCDEFGHIKKLMN"};
char ch1[15] {};
str5.copy(ch1,6,4);
cout<<ch1<<endl;//EFGHIK
11.resize()方法
11-1 resize(n) 将字符串重新调整成长度为n,多出的空间填充'\0'
string str6{"ABCDE"};
str6.resize(8);
for(size_t i=0;i<str6.size();i++){
cout<<i<<" "<<str6[i]<<endl;
}
//可以看到编号567 后面都是 空字符
11-2 resize(n,ch) 将字符串重新调整成长度为n,多出的空间填充char类型ch
string str7{"ABCDE"};
str7.resize(10,'*');
for(size_t i=0;i<str7.size();i++){
cout<<i<<" "<<str7[i]<<endl;
}
11-3 resize(n) n也可以比原来的长度小,多出的字符自动删除,
12 swap()方法
strA.swap(strB) 将两个字符串内容相互交换
13. 查找 find方法
13-1 strA.find(strB) 返回下标,如果没有,就返回一个巨大的数字
这个巨大的数字叫做string:: npos
cout<<string::npos<<endl;
所以可以根据它判断有没有找到
string str10{"Reading books is good"};
string str11{ "good"};
string str12 {"chicken"};
size_t find_pos =str10.find(str12);
if(find_pos==string::npos){
cout<<"没有找到!"<<endl;
}
else{
cout<<"找到了!"<<endl;
cout<<find_pos<<endl;
}
13-2 strA.find(strB,n)从位置n开始搜索strA
strB也可以用const char*{"abcd"} 这种形式。
在文档里还有
find_first_of ,
find_first_not_of ,
find_last_of,
find_last_not_of
14. escape characters 我感觉应该是转义字符吧
“D:\vscode site\帮助文件 ”类似于这种字符串,是不行的,因为\跟后面的字符直接变成转义字符,成了别的含义,编译器报错 。必须写成 \\
string window_str15{"D:\\vscode site\\帮助文件"};
string Linix_str16{"/home/user/panting.txt"};
cout<<window_str15<<endl;
cout<<Linix_str16<<endl;
如果想打出双引号,必须在每一个双引号前面加\
比方说,想打出下面这句话:
“ \\ ” escapes a 反斜线字符 like " \ "
string str17{" \" \\\\ \" escapes a 反斜线字符 like \" \\ \" "};
// 解释: \" 是转义一半双引号,打出来是"
// 解释: \\\\ 打出来是 \\ 每一个\\是用来转义\
15.一堆斜线眼花缭乱,开始raw literals
比如,想输出3行左对齐缩进相同的英文,应该这样:
string str18{
"\twash the dish\n\tclean the clothes\n\tget the post\n"
};
现在用raw string 字面量
string str19{R"(
wash the dish
clean the clothes
get the post
)"};
cout<<str19<<endl;
现在在屏幕上缩进多少,打印出来就缩进多少 。也可以直接赋值
string str20=R"(
The dog is chasing
the fox. OH NO!
)";
那么上面那些类似于路径的字符串就可以直接照原样打印
string win{R"(D:\vscode site\cat1\anoth\111.txt)"};
string hint{R"(\\是转义字符,转了一个\)"};
双引号和括号在字符串中的时候,Raw字符串会报错,因为括号里又出现了括号。
比如我们想输出 He said,"(a beautiful carafe)".Then he picked up it.
这时候在括号外侧加--- 表示括号内的内容是raw string
string str21{R"---(He said,"(a beautiful carafe)".Then he picked up it.)---"};
16.拷贝构造函数初始化字符串时,节省内存的方法 ——创建引用。
这种方式,用两块内存放了两个相同的字符串,造成了内存的浪费。如何解决呢
string str22{"West 130km of the city"};
string str23{str22}; //str23(str22)小括号也行
const char* p1=str22.data();
const char* p2=str23.data();
cout<<p1<<endl;
cout<<p2<<endl;
//这时候p1 p2都是字符数组指针所以,打印出来都是
// West 130km字符串原来内容而已
//现在打印地址了 可以看到两个地址相差32位 4字节?
cout<<(void*)p1<<endl;
cout<<(void*)p2<<endl;
//现在如何让两个内存相同呢
改成引用 拷贝构造函数
string str24{"Come here"};
string& str25(str24);
17.String_view
String_view类似于一个窗口,将字符串信息复制过来,没有占用新的内存。透过这个小窗口,如同管中窥豹一样,去窥视原来字符串的信息。我们怎样遮蔽修改这个小窗口,原来的字符串信息都是不会改动的。
直接改动原有字符串,视口也会发生变化。
参考文字string_View理解与用法(一)_absl::string_view_荆楚闲人的博客-CSDN博客
不知道为什么我用的devC++里没有string_view这个类 可能是不支持C++17
经过一桶捣鼓参考这个文章【应用】让Dev-C++ 支持C++20标准_dev c++20_行码棋的博客-CSDN博客
17-1 string_view的声明和初始化
string str26{"The animals have their own region and land"};
const char* str27{"Regular C-string"};
const char char_array[]{"char array string"};
char char_array2[]{'c','i','n','e','m','a'};//cinema
string_view sv1{"literal string"};
string_view sv2{str26};
string_view sv3{str27};
string_view sv4{sv3};
string_view sv5{char_array};
//因为char_array2不是以Null结尾的,所以要加上长度
string_view sv6{char_array2,size(char_array2)};
cout<<sv1<<endl;
cout<<sv2<<endl;
cout<<sv3<<endl;
cout<<sv4<<endl;
cout<<sv5<<endl;
cout<<sv6<<endl;
17.2 就像一个窗口,从前面和后面拉上窗帘,就可以调整视口看到的字符串的面貌
sv2.remove_prefix(4);
cout<<sv2<<endl;//animals have their own region and land 去掉了the
sv2.remove_suffix(10);
cout<<sv2<<endl; //animals have their own regio
//注意,当这样修改后,string_view data() modified
string_view sv7{"ticket"};
sv7.remove_prefix(2);
sv7.remove_suffix(2);
cout<<sv7<<endl;//ck
cout<<sv7.data()<<endl;//cket remove_suffix好像忘了
cout<<strlen(sv7.data())<<endl;//4
17-3. 很多string的方法, string_view也可以适用
//string_view 拥有most of String method
string_view sv8{"here is a huge forest"};
cout<<sv8.length()<<endl;
cout<<sv8.front()<<endl;
cout<<sv8.back()<<endl;
cout<<sv8.substr(0,7) <<endl;