一. string的构造函数的形式
string str:生成空字符串 eg: string str1; //生成空字符串
string s(str):生成字符串为str的复制品(直接初始化,下图string s2=s1为拷贝初始化) eg: string str2("123456789"); //生成"1234456789"的复制品
string s(str, strbegin,strlen):将字符串str中从下标strbegin开始、长度为strlen的部分作为字符串初值 eg: string str3("12345", 0, 3);//结果为"123"
string s(cstr, char_len):以C_string类型cstr的前char_len个字符串作为字符串s的初值 eg: string str4("012345", 5); //结果为"01234"
string s(str, stridx):将字符串str中从下标stridx开始到字符串结束的位置作为字符串初值 eg: string str6(str2, 2); //结果为"3456789"
string s(num ,c):生成num个c字符的字符串 eg: string str5(5, '1'); //结果为"11111"
综上:尽量使用直接初始化,即:string s(str)
二. string的大小和容量
1.str.length()/size()
length是因为沿用C语言的习惯而保留下来的,string类最初只有length,引入STL之后,为了兼容又加入了size,它是作为STL容器的属性存在的,便于符合STL的接口规则,以便用于STL的算法。 string类的size()/length()方法返回string对象的字符个数,他们执行效果相同。
成员函数empty()用来检验字符数是否为0,亦即字符串是否为空。你应该优先使用该函数,因为它比length()或size()来得快。
也就是说,使用== if(s.empty() true)而不使用if(s.size() == 0)
2.容量
-
size()和length():返回string对象的字符个数,他们执行效果相同。
-
max_size():返回string对象最多包含的字符数,超出会抛出length_error异常
-
capacity():重新分配内存之前,string对象能包含的最大字符数
三. string对象上的操作
1. C ++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),
支持string与C-string的比较(如 str<”hello”)。 --C语言中字符串以字符数组的形式存储,以’\0’结尾,而C++中引入了string类作为字符串类型,其转换关系如链接
在使用>,>=,<,<=这些操作符的时候是根据“当前字符特性”将字符按字典顺序进行逐一得 比较。字典排序靠前的字符小, 比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小(前面减后面)
同时,string (“aaaa”) <string(aaaaa)。
补充:
(1)C++中,string类能够自动将C 语言字符串转换成string对象
#include <iostream>
#include <string>
int main(){
const char *s = "Roger!";
std::string str1(s);
std::string str2 = s;
std::string str3("Emm");
str3 = s;
std::cout << "C str:" << s << std::endl;
std::cout << "C++ str1:" << str1 << std::endl;
std::cout << "C++ str2:" << str2 << std::endl;
std::cout << "C++ str3:" << str3 << std::endl;
}
(2)C++提供的由C++字符串转换成对应的C字符串的方法是使用data()、c_str()和copy()来实现。
data():以字符数组的形式返回字符串的内容,但并不添加’\0’
c_str():返回一个以’\0’结尾的字符数组
copy():把字符串的内容复制或写入既有的c_string或字符数组内。
注意:C++字符串并不以’\0’结尾。
**c_str()语句可以生产一个const char *指针,并指向字符数组。**这个数字的数据是临时的,当有一个改变这些数据的成员函数被调用,其中的数据就会失效。因此,要么现用现转换,要么把它的数据复制到用户自己可以管理的内存后再转换。
#include<iostream>
#include<string>
using namespace std;
int main(){
string str="Hello world.";
const char * cstr=str.c_str();
cout<<cstr<<endl; //Hello world.,此处若为*cstr则结果为H
str="Abcd.";
cout<<cstr<<endl; //Abcd.此处若为*cstr则结果为A
return 0;
}
2. 成员函数compare()。
此比较函数支持多参数处理,支持用索引值和长度定位子串来进行比较。
他返回一个整数来表示比较结果,返回值意义如下:0:相等 1:大于 -1:小于 (A的ASCII码是65,a的ASCII码是97)
void test3()
{
// (A的ASCII码是65,a的ASCII码是97)
// 前面减去后面的ASCII码,>0返回1,<0返回-1,相同返回0
string A("aBcd");
string B("Abcd");
string C("123456");
string D("123dfg");
// "aBcd" 和 "Abcd"比较------ a > A
cout << "A.compare(B):" << A.compare(B)<< endl; // 结果:1
// "cd" 和 "Abcd"比较------- c > A
cout << "A.compare(2, 3, B):" <<A.compare(2, 3, B)<< endl; // 结果:1
// "cd" 和 "cd"比较
cout << "A.compare(2, 3, B, 2, 3):" << A.compare(2, 3, B, 2, 3) << endl; // 结果:0
// 由结果看出来:0表示下标,3表示长度
// "123" 和 "123"比较
cout << "C.compare(0, 3, D, 0, 3)" <<C.compare(0, 3, D, 0, 3) << endl; // 结果:0
}
3.string的插入:push_back() 和 insert()
void test4()
{
string s1;
// 尾插一个字符
s1.push_back('a');
s1.push_back('b');
s1.push_back('c');
cout<<"s1:"<<s1<<endl; // s1:abc
// insert(pos,char):在制定的位置pos前插入字符char
s1.insert(s1.begin(),'1');
cout<<"s1:"<<s1<<endl; // s1:1abc
}
4.string的删除—string.erase() 的用法
(1)string.erase(pos,n)
删除从pos开始的n个字符 string.erase(0,1); 删除第一个字符
#include <string>
#include <iostream>
using namespace std;
int main()
{
string::iterator i;
string s;
cin>>s;
s.erase(1,2);
cout<<s;
return 0;
}
(2) string.erase(pos)
删除pos处的一个字符(pos是string类型的迭代器)
#include <string>
#include <iostream>
using namespace std;
int main()
{
string::iterator i;
string s;
cin>>s;
i = s.begin()+3;
s.erase(i);
cout<<s;
return 0;
}
(3)string.erase(first,last)
删除从first到last中间的字符(first和last都是string类型的迭代器)
#include <string>
#include <iostream>
using namespace std;
int main()
{
string::iterator i;
string s;
cin>>s;
s.erase(s.begin()+1,s.end()-1);
cout<<s;
return 0;
}
(4)void clear();
删除字符串中所有字符
5.string的遍历
借助迭代器 或者 下标法
void test()
{
string s1("abcdef"); // 调用一次构造函数
// 方法一: 下标法
for( int i = 0; i < s1.size() ; i++ )
{
cout<<s1[i];
}
cout<<endl;
// 方法二:正向迭代器
string::iterator iter = s1.begin(); //auto iter = s1.begin(),使用auto让编译器自动推断iter类型
for( ; iter < s1.end() ; iter++)
{
cout<<*iter;
}
cout<<endl;
// 方法三:反向迭代器
string::reverse_iterator riter = s1.rbegin();
for( ; riter < s1.rend() ; riter++)
{
cout<<*riter;
}
cout<<endl;
}
6.string.replace()
(1). string& replace(size_t pos, size_t n, const char *s);
将当前字符串从pos索引开始的n个字符,替换成字符串s
(2). string& replace(size_t pos, size_t n, size_t n1, char c);
将当前字符串从pos索引开始的n个字符,替换成n1个字符c
(3). string& replace(iterator i1, iterator i2, const char* s);
将当前字符串[i1,i2)区间中的字符串替换为字符串s
void test()
{
string s1("hello,world!");
cout<<s1.size()<<endl; // 结果:12
s1.replace(s1.size()-1,1,1,'.'); // 结果:hello,world.
// 这里的6表示下标 5表示长度
s1.replace(6,5,"girl"); // 结果:hello,girl.
// s1.begin(),s1.begin()+5 是左闭右开区间
s1.replace(s1.begin(),s1.begin()+5,"boy"); // 结果:boy,girl.
cout<<s1<<endl;
}
7.string的大小写转换:tolower()和toupper()函数 或者 STL中的transform算法
(1) 使用C语言之前的方法,使用函数,进行转换
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s = "ABCDEFG";
for( int i = 0; i < s.size(); i++ )
{
s[i] = tolower(s[i]);
}
cout<<s<<endl;
return 0;
}
(2) 通过STL的transform算法配合的toupper和tolower来实现该功能
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
string s = "ABCDEFG";
string result;
transform(s.begin(),s.end(),s.begin(),::tolower);
cout<<s<<endl;
return 0;
}
8.string的查找:find()
(1)size_t find (const char s, size_t pos = 0) const;*
在当前字符串的pos索引位置开始,查找子串s,返回找到的位置索引,
-1表示查找不到子串
(2) size_t find (char c, size_t pos = 0) const;
在当前字符串的pos索引位置开始,查找字符c,返回找到的位置索引,
-1表示查找不到字符
(3) size_t rfind (const char s, size_t pos = npos) const;*
在当前字符串的pos索引位置开始,反向查找子串s,返回找到的位置索引,
-1表示查找不到子串
(4)size_t rfind (char c, size_t pos = npos) const;
在当前字符串的pos索引位置开始,反向查找字符c,返回找到的位置索引,-1表示查找不到字符
(5) size_t find_first_of (const char s, size_t pos = 0) const;*
在当前字符串的pos索引位置开始,查找子串s的字符,返回找到的位置索引,-1表示查找不到字符
(6) size_t find_first_not_of (const char s, size_t pos = 0) const;*
在当前字符串的pos索引位置开始,查找第一个不位于子串s的字符,返回找到的位置索引,-1表示查找不到字符
(7) size_t find_last_of(const char s, size_t pos = npos) const;*
在当前字符串的pos索引位置开始,查找最后一个位于子串s的字符,返回找到的位置索引,-1表示查找不到字符
(8)size_t find_last_not_of (const char s, size_t pos = npos) const;*
在当前字符串的pos索引位置开始,查找最后一个不位于子串s的字符,返回找到的位置索引,-1表示查找不到子串
void test8()
{
string s("dog bird chicken bird cat");
//字符串查找-----找到后返回首字母在字符串中的下标
// 1. 查找一个字符串
cout << s.find("chicken") << endl; // 结果是:9
// 2. 从下标为6开始找字符'i',返回找到的第一个i的下标
cout << s.find('i',6) << endl; // 结果是:11
// 3. 从字符串的末尾开始查找字符串,返回的还是首字母在字符串中的下标
cout << s.rfind("chicken") << endl; // 结果是:9
// 4. 从字符串的末尾开始查找字符
cout << s.rfind('i') << endl; // 结果是:18-------因为是从末尾开始查找,所以返回第一次找到的字符
// 5. 在该字符串中查找第一个属于字符串s的字符
cout << s.find_first_of("13br98") << endl; // 结果是:4---b
// 6. 在该字符串中查找第一个不属于字符串s的字符------先匹配dog,然后bird匹配不到,所以打印4
cout << s.find_first_not_of("hello dog 2006") << endl; // 结果是:4
cout << s.find_first_not_of("dog bird 2006") << endl; // 结果是:9
// 7. 在该字符串最后中查找第一个属于字符串s的字符
cout << s.find_last_of("13r98") << endl; // 结果是:19
// 8. 在该字符串最后中查找第一个不属于字符串s的字符------先匹配t--a---c,然后空格匹配不到,所以打印21
cout << s.find_last_not_of("teac") << endl; // 结果是:21
}
9. string的排序:sort(s.begin(),s.end())
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
void test9()
{
string s = "cdefba";
sort(s.begin(),s.end());
cout<<"s:"<<s<<endl; // 结果:abcdef
}
### 10.分割/截取字符串函数:strtok() & substr()
四.字符串其它问题
1.c语言 如何用指针来处理字符串?
为什么字符指针指向字符串的时候,输出时不需要再指针前加*号呢?
1.因为iostream的<<运算符有对char类型的重载,但是没有对int的重载
2.char *str这个定义了一个类型为char 的字符型指针str ,而str指向了 I LOVE CHINA!中的第一个字符I,后面的cout流里面有一个循环就是输出str指向的字符串,其中把str赋给了temp指针,作为移位用,从而一个个输出出来。而str是一个字符了 就是I ,是解引用 就是读出str指向的字符 ,所以str就是I了 这个是不能赋值和移位的 所以输出不出来!!!
3.参考3
4.参考4