C++_string类常用接口

string类的常用接口

(1)string类对象的常见构造

  • string():构造空的string类对象,即空字符串
  • string(const char * s):用C-string来构造string类对象
  • string(size_t n, char c):string类对象中包含n个字符c
  • string(const string& s):拷贝构造函数
#include<cstring>
#include<iostream>

using namespace std;

int main()
{
	string s1;
	string s2("hello");
	string s3(5, 'a');
	string s4(s3);
	cout<<s1<<endl;
	cout<<s2<<endl;
	cout<<s3<<endl;
	cout<<s4<<endl;
	return 0;
}

(2)string类对象的容量操作

  • size():返回字符串有效字符长度
  • length():返回字符串有效字符长度
  • capacity():返回空间总大小
  • empty():检测字符串是否为空串
  • clear():清空有效字符
  • reserve(size_t n):为字符串预留空间
  • resize(size_t n, char c):将有效字符个数改成n个,多出的空间用字符c填充
#include<iostream>
#include<cstring>

using namespace std;

//size/length/capacity/clear/resize
void test_string_1()
{
	string s("hello");
	cout<<s<<endl;//hello
	cout<<s.size()<<endl;//5
	cout<<s.length()<<endl;//5
	cout<<s.capacity()<<endl;//15

	s.clear();
	cout<<s<<endl;//
	cout<<s.size()<<endl;//0
	cout<<s.capacity()<<endl;//15

	s.resize(10, 'a');
	cout<<s<<endl;//aaaaaaaaaa
	cout<<s.size()<<endl;//10
	cout<<s.capacity()<<endl;//15

	s.resize(15);
	cout<<s<<endl;//aaaaaaaaaa\0\0\0\0\0
	cout<<s.size()<<endl;//15
	cout<<s.capacity()<<endl;//15

	s.resize(5);
	cout<<s<<endl;//aaaaa
	cout<<s.size()<<endl;//5
	cout<<s.capacity()<<endl;//15
}

//reserve
void test_string_2()
{
	string s;
	s.reserve(100);
	cout<<s.size()<<endl;//0
	cout<<s.capacity()<<endl;//100

	s.reserve(50);
	cout<<s.size()<<endl;//0
	cout<<s.capacity()<<endl;//50
}

//用reserve提高插入效率,避免增容带来的开销
//有开销
void test_pushBack()
{
	string s;
	size_t sz = s.capacity();
	for(int i = 0; i < 100; ++i)
	{
		s.push_back('c');
		if(sz != s.capacity())
		{
			sz = s.capacity();
			cout<<sz<<endl;
		}
	}
	cout<<s<<endl;
}

//无开销
void test_pushBack_reserve()
{
	string s;
	s.reserve(100);
	size_t sz = s.capacity();
	for(int i = 0; i < 100; ++i)
	{
		s.push_back('c');
		if(sz != s.capacity())
		{
			sz = s.capacity();
			cout<<sz<<endl;
		}
	}
	cout<<s<<endl;
}

int main()
{
	test_string_1();
	cout<<endl;
	test_string_2();
	cout<<endl;
	test_pushBack();
	cout<<endl;
	test_pushBack_reserve();
	return 0;
}
  • size()与length()实现原理相同,引入size()是为了与其他容器接口保持一致
  • clear()只是将字符串中有效字符清空,不改变底层空间大小
  • resize(size_t n)与resize(size_t n, char c)都是将字符串有效字符个数改变到n
  • reserve(size_t n)为字符串预留空间,不改变有效元素个数

(3)string类对象的访问及遍历操作

  • operator[]:返回pos位置字符,const string类对象调用
  • begin()+end():begin获取一个字符的迭代器,end获取最后一个字符下一个位置的迭代器
  • rbegin()+rend():begin获取一个字符的迭代器,end获取最后一个字符下一个位置的迭代器
  • 范围for:C++11
#include<iostream>
#include<cstring>

using namespace std;

void test_string_1()
{
	string s1("hello");
	const string s2("HELLO");
	cout<<s1<<" "<<s2<<endl;
	cout<<s1[0]<<" "<<s2[0]<<endl;
	s1[0] = 'H';
	cout<<s1<<endl;
	//s2[0] = 'h';const不可修改
}

void test_string_2()
{
	string s("Hello");

	//for+operator[]
	for(size_t i = 0; i < s.size(); ++i)
	{
		cout<<s[i]<<" ";
	}
	cout<<endl;

	//迭代器
	string::iterator it = s.begin();
	while(it != s.end())
	{
		cout<<*it<<" ";
		++it;
	}
	cout<<endl;

	string::reverse_iterator rit = s.rbegin();
	while(rit != s.rend())
	{
		cout<<*rit<<" ";
		++rit;
	}
	cout<<endl;

	//范围for:C++11
	for(auto ch : s)
	{
		cout<<ch<<" ";
	}
	cout<<endl;
}

int main()
{
	test_string_1();
	cout<<endl;
	test_string_2();
	return 0;
}

(4)string类对象的修改操作

  • push_back(char c):字符串后尾插字符c
  • append(const string s):字符串后追加字符串
  • operator+=:在字符串后追加字符串
  • c_str():返回C格式字符串
  • find()+npos:从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
  • rfind():从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
  • substr(size_t pos, size_t n):在字符串中从pos位置开始,截取n个字符返回
#include<iostream>
#include<cstring>

using namespace std;

int main()
{
	string str;
	str.append("Hello");
	str.push_back(' ');
	str += "Linux";
	cout<<str<<endl;
	cout<<str.c_str()<<endl;

	//获取文件后缀
	string file("file.cpp");
	cout<<file<<endl;
	size_t pos = file.find('.');
	string suffix(file.substr(pos, file.size()-pos));
	cout<<suffix<<endl;

	//截取url中的域名
	string url("http://github.com/lhn-debug/workspace.git");
	cout<<url<<endl;
	size_t start = url.find("://");
	//static const size_t npos = -1
	//npos是string中的一个静态成员变量
	if(start == string::npos)
	{
		cout<<"invalid url"<<endl;
		return 0;
	}
	start += 3;
	size_t end = url.find('/', start);
	string address = url.substr(start, end - start);
	cout<<address<<endl;

	//删除url的协议前缀
	size_t del = url.find("://");
	url.erase(0, pos + 3);
	cout<<url<<endl;
	return 0;
}

(5)string类非成员函数

  • operator+:尽量少用,传值返回,深拷贝效率低
  • operator>>:输入运算符重载
  • operator<<:输出运算符重载
  • getline:获取一行字符串
  • relational operators:大小比较

几个例子

(1)翻转字符串

#include<iostream>

using namespace std;

string reverseString(string s)
{
	if(s.empty())
	{
		return s;
	}
	size_t start = 0;
	size_t end = s.size() - 1;
	while(start < end)
	{
		swap(s[start], s[end]);
		++start;
		--end;
	}
	return s;
}

int main()
{
	string s("hello");
	string str = reverseString(s);
	cout<<s<<endl;
	cout<<str<<endl;
	return 0;
}

(2)找字符串中第一个只出现一次的字符

#include<iostream>

using namespace std;

int firstUniqChar(string s)
{
	if(s.empty())
	{
		return -1;
	}
	int count[256] = {0};
	for(int i = 0; i < s.size(); ++i)
	{
		count[s[i]]++;
	}
	for(int i = 0; i < s.size(); ++i)
	{
		if(count[s[i]] == 1)
		{
			return i;
		}
	}
	return -1;
}

int main()
{
	string s = "dskasbfkaffnd";
	int pos = firstUniqChar(s);
	cout<<pos<<endl;
	cout<<s<<endl;
	if(pos != -1)
	{
		cout<<s[pos]<<endl;
	}
}

(3)字符串里最后一个字符长度

#include<iostream>

using namespace std;

void lastWordLength()
{
	string line;
	while(getline(cin, line))
	{
		size_t pos = line.rfind(' ');
		cout<<line.size()-pos-1<<endl;
	}
}

int main()
{
	lastWordLength();
	return 0;
}
发布了72 篇原创文章 · 获赞 25 · 访问量 7335

猜你喜欢

转载自blog.csdn.net/qq_41245381/article/details/103975789