C语言中的字符串:C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。 C++标准库中的string类:在使用string类时,必须包含#include头文件以及using namespace std;
1. string是表示字符串的字符串类
2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
4. 不能操作多字节或者变长字符的序列。
string类对象的常见构造:
void main()
{
string s1;
cout << "s1= " << s1 << endl;
string s2("HelloBit");
cout << "s2= " << s2 << endl;
string s3 = "HelloBitA";
cout << "s3= " << s3 << endl;
string s4(5, 'a');
cout << "s4= " << s4 << endl;
string s5(s4);
cout << "s5= " << s5 << endl;
string s6(s2, 5, 3);
cout << "s6= " << s6 << endl;
string s7("HelloBit", 5);
cout << "s7= " << s7 << endl;
const char* str = "abcdefg";
string s8(str + 1, str + 4);
cout << "s8= " << s8 << endl;
}
string类对象容量操作:
void main()
{
string s1;
cout << "s1= " << s1 << endl;
cout << "size=" << s1.size() << endl;
cout << "capacity= " << s1.capacity() << endl;
s1.resize(20, '@');
cout << "s1= " << s1 << endl;
cout << "size=" << s1.size() << endl;
cout << "capacity= " << s1.capacity() << endl;
s1.resize(30, 'a');
cout << "s1= " << s1 << endl;
cout << "size=" << s1.size() << endl;
cout << "capacity= " << s1.capacity() << endl;
}
void main()
{
string s1;
cout << "s1= " << s1 << endl;
cout << "size=" << s1.size() << endl;
cout << "capacity= " << s1.capacity() << endl;
s1.reserve(100);
cout << "s1= " << s1 << endl;
cout << "size=" << s1.size() << endl;
cout << "capacity= " << s1.capacity() << endl;
s1.reserve(10);
cout << "s1= " << s1 << endl;
cout << "size=" << s1.size() << endl;
cout << "capacity= " << s1.capacity() << endl;
}
void main()
{
string s1("HelloBit");
cout << "s1= " << s1 << endl;
cout << "size=" << s1.size() << endl;
cout << "length= " << s1.length() << endl;
cout << "capacity= " << s1.capacity() << endl;
s1 += "abcdefghij";
cout << "s1= " << s1 << endl;
cout << "size=" << s1.size() << endl;
cout << "length= " << s1.length() << endl;
cout << "capacity= " << s1.capacity() << endl;
}
void main()
{
string s1("HelloBit");
cout << "s1= " << s1 << endl;
cout << "size=" << s1.size() << endl;
cout << "length= " << s1.length() << endl;
cout << "capacity= " << s1.capacity() << endl;
s1.clear();
cout << "s1= " << s1 << endl;
string s2;
cout << s2.empty() << endl;
}
注意:利用reserve函数可以提高插入数据的效率,避免增容的开销。
void main()
{
string s;
cout << "capacity= " << s.capacity() << endl;
s.reserve(100);
for (int i = 0;i <= 100;++i)
{
cout << "capacity= " << s.capacity() << endl;
s.push_back(i + 1);
}
}
1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
2. clear()只是将string中有效字符清空,不改变底层空间大小。
3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
string类对象的访问及遍历操作:
void main()
{
string s1("abcdxyz");
string::iterator it = s1.begin();
while (it != s1.end())
{
cout << *it;
++it;
}
cout << endl;
cout << s1 << endl;
for (const auto& e : s1)
cout << e;
cout << endl;
for (int i = 0;i < s1.size(); ++i)
cout << s1[i];
cout << endl;
string::reverse_iterator rit = s1.rbegin();
while (rit != s1.rend())
{
cout << *rit;
++rit;
}
cout << endl;
string类对象的修改操作:
void main()
{
string s = "abxyccb";
cout << "s= " << s << endl;
string s1 = s.substr(2,5);
string s1 = s.substr(2);
cout << "s1= " << s1 << endl;
}
void main()
{
string s = "abxcxyz";
int index = s.find('x');
cout << "index= " << index << endl;
int index = s.find('x', 3);
int index = s.find("xyz");
int index = s.find("xyz", 4, 3);
int index = s.rfind('x');
if (index == string::npos)
cout << "找不到" << endl;
else
cout << "index= " << index << endl;
}
void main()
{
string s("abc");
strlen(s.c_str());
}
void main()
{
string s("abc");
string s1("qwe");
s += s1;
cout << "s= " << s << endl;
}
void main()
{
string s = ("abc");
string s1 = ("qwer");
cout << "s= " << s << endl;
s.push_back('x');
s.append("xyz");
s.append("xyz", 2);
s.append(s1, 0, 3);
s.append(3,'x');
cout << "s= " << s << endl;
}
注意:
1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
string类非成员函数:多补充以下几个接口使用
void main()
{
string s1 = "abcxyzab";
int index = s1.find_first_of('b');
int index = s1.find_first_of("yxz");
int index = s1.find_first_not_of("yxza");
int index = s1.find_last_of("yxza");
cout << index << endl;
}
void main()
{
string s1 = "abc";
string s2 = "xyz";
s1.swap(s2);
cout << s1 << endl;
cout << s2 << endl;
}
void main()
{
string s1 = "aac";
s1.insert(0, "xyz");
s1.erase(2, 5);
cout << s1 << endl;
}
void main()
{
string s1 = "aac";
string s2 = "aac";
if (s1.compare(s2) == 0)
cout << "s1==s2" << endl;
}
void main()
{
string s1 = "abc";
for (int i = 0;i < s1.size();++i)
cout << s1[i];
cout << endl;
for (int i = 0;i < s1.size();++i)
cout << s1.at(i);
cout << endl;
}
void main()
{
string s1 = "abc";
string s2 = "xyzsadasdassd";
s1.assign(s2);
cout << "s1" << endl;
}
void main()
{
string s1 = "abc";
string s2 = "xyz";
if (s1 > s2)
cout << "s1>s2" << endl;
else
cout << "s2<s1" << endl;
}
void main()
{
string s;
getline(cin, s);
cout << s << endl;
}
void main()
{
string s1 = "abc";
string s2 = "xyz";
string s = s1 + s2;
cout << s << endl;
}
|