string类

本文详细介绍了C++中的string类,包括其概念、C语言中的字符串处理、C++中string类的定义和特性,以及各种成员函数如迭代器、容量管理、操作字符串等的使用示例。同时涵盖了字符串分解和内存管理的区别等内容。
摘要由CSDN通过智能技术生成

string类

如何学习string类呢?为什么学习string类呢?

C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不符合面向对象编程的思想,需要用户自己管理,稍不留神可能会越界访问

  1. 熟悉String类
  2. 熟悉各种String接口用法
  3. 熟练运用String类解决问题

C++中对于string的定义为:typedef basic_string string,C++中的string类是一个泛型类,是模板实例化的一个标准类,本质上不是一个标准数据类型。

总结:

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
    比特就业课
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>
    string;
  4. 不能操作多字节或者变长字符的序列。

string类参考文档:cplusplus.com/reference/string/string/

string 类接口学习

Member functions

  • Iterators
  • Capacity
  • Element access
  • Modifiers
  • String operations
#include<iostream>
#include<string.h>
using namespace std;
void teststring()
{

	string s1("hello nihao shijie");
	string s2(s1);
	string s3(s1, 5);
	string s4("hello world");
	string s5(10, 'a');
	string s6 = s5;
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;
}
// strng类类似数组的遍历方式
void test1()
{
	string s1("hello world");
	for (int i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
}
// 迭代器:通用遍历方式
void test2()
{
	string s1("hello world");
	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		cout << *it1 << " ";
		it1++;
	}
}
// 反向迭代器:
void test3()
{
	string s1("hello world");
	string::reverse_iterator rit1 = s1.rbegin();
	while (rit1 != s1.rend())
	{
		cout << *rit1 << " ";
		rit1++;
	}
}
//
void test4()
{
	string s1("hello world");
	// 历史遗留问题,规范多用size
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	// 返回字符串的最大大小
	cout << s1.max_size() << endl;
	// 返回分配存储的大小
	cout << s1.capacity() << endl;
	// vs下扩容机制是第一次两倍,后面为1.5倍
	// linux下g++是两倍扩容

	// 清除字符串,clear()只是将string中有效字符清空,不改变底层空间大小
	cout << s1 << endl;
	s1.clear();
	cout << s1 << endl;
	cout << s1.capacity() << endl;
}
// reserve扩容
void test5()
{

	string s1("hello world");
	cout << s1.size() << endl;

	// 不同编译器厂家底层实现扩容细节不同,vs下此处扩容不是给的100
	s1.reserve(100);//更改容量
	cout << s1.capacity() << endl;;
}
// resize改变string大小
void test6()
{
	std::string str("I like to code in C");
	std::cout << str << '\n';

	unsigned sz = str.size();

	str.resize(sz + 2, '+');
	std::cout << str << '\n';

	str.resize(14);
	std::cout << str << '\n';
}
// string追加:append和push_back(不是最香的)
void test7()
{
	string s1("hello world");
	cout << s1[5] << endl;
	cout << s1.at(5) << endl;
	s1.push_back('a');
	cout << s1 << endl;
	string s2("i like ");
	s2.append("apple");
	cout << s2 << endl;
}
// string追加:+=(最香的)
void test8()
{
	string s1("i like eat");
	s1 += ' ';
	s1 += "apple";
	cout << s1 << endl;

}

// Assigns a new value to the string, replacing its current contents
// string替换:assign
void test9()
{
	string s1("zht");
	cout << s1 << endl;
	s1.assign("hhhhhh");
	cout << s1 << endl;
}

// erase 和 insert
// 底层实现类似于顺序表,删除添加需要挪动数据,所以时间复杂度为O(N),效率不高
void test10()
{
	string s1("hello world");
	cout << s1 << endl;
	s1.erase();
	cout << s1 << endl;

}
// find 和 replace
void test11()
{
	// 找寻空格位置并且从该位置开始将一个字符位置替换为:"%100"
	string s1("hello world hello bit");
	size_t pos = s1.find(' ');
	while (pos != string::npos)
	{
		s1.replace(pos, 1, "%100");
		pos = s1.find(' ');
	}
	cout << s1 << endl;
}
void test12()
{
	std::string firstlevel("com");
	std::string secondlevel("cplusplus");
	std::string scheme("http://");
	std::string hostname;
	std::string url;

	hostname = "www." + secondlevel + '.' + firstlevel;
	url = scheme + hostname;

	std::cout << url << '\n';

}
void test13()
{
	string s1("123456789");
	cout << s1.size() << endl;
}
int main()
{
	test1();
	test2();
	test3();
	test4();
	test5();
	test6();
	test7();
	test8();
	test9();
	test10();
	test11();
	test12();
	test13();
	return 0;
}
  1. size()length()方法底层实现原理完全相同
  2. clear()只是将string中有效字符清空,不改变底层空间大小
  3. resize(size_t n)resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize用0来填充多出的元素空间,resize用字符c来填充多出的元素空间。resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变
  4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小

string类的使用示例

域名分解:

#include<iostream>
#include<string.h>
using namespace std;
void Break_down_the_domain_name(string URL)
{
	string url;
	url = URL;
	string protocol, domain, uri;
	size_t pos_protocol = url.find(':');
	if (pos_protocol != string::npos)
	{
		cout << "protocol:" << url.substr(0, pos_protocol - 0) << endl;
	}
	else
	{
		cout << "no protocol" << endl;
	}
	size_t pos_domain = url.find('/', pos_protocol + 3);
	if (pos_domain != string::npos)
	{
		cout << "domain:" << url.substr(pos_protocol + 3, pos_domain - (pos_protocol + 3)) << endl;
	}
	else
	{
		cout << "no domain" << endl;
	}
	size_t pos_uri = pos_domain + 1;
	if (pos_uri != string::npos)
	{
		cout << url.substr(pos_uri) << endl;
	}
	else
	{
		cout << "no uri" << endl;
	}

}
int main()
{
	string url("https://cplusplus.com/reference/string/basic_string/copy/");
	Break_down_the_domain_name(url);
	return 0;
}

#include<iostream>
#include<string.h>
using namespace std;

// 域名分解
void Break_down_the_domain_name(string URL)
{
	string url;
	url = URL;
	string protocol, domain, uri;
	size_t pos_protocol = url.find(':');
	if (pos_protocol != string::npos)
	{
		cout << "protocol:" << url.substr(0, pos_protocol - 0) << endl;
	}
	else
	{
		cout << "no protocol" << endl;
	}
	size_t pos_domain = url.find('/', pos_protocol + 3);
	if (pos_domain != string::npos)
	{
		cout << "domain:" << url.substr(pos_protocol + 3, pos_domain - (pos_protocol + 3)) << endl;
	}
	else
	{
		cout << "no domain" << endl;
	}
	size_t pos_uri = pos_domain + 1;
	if (pos_uri != string::npos)
	{
		cout << url.substr(pos_uri) << endl;
	}
	else
	{
		cout << "no uri" << endl;
	}
}
int main()
{
	string url("https://cplusplus.com/reference/string/basic_string/copy/");
	Break_down_the_domain_name(url);
	return 0;
}

int main(int argc, char* argv[])
{
    string a = "hello world";
    string b = a;

    if (a.c_str() == b.c_str())
        cout << "true" << endl;
    else
        cout << "false" << endl;

    string c = b;
    c = "";

    if (a.c_str() == b.c_str())
        cout << "true" << endl;
    else
        cout << "false" << endl;

    a = "";
    if (a.c_str() == b.c_str())
        cout << "true" << endl;
    else
        cout << "false" << endl;

    return 0;
}

// 注意resize和reserve的区别:resize()函数是修改string对象的实际大小,而reserve()函数是预留string对象的潜在空间
int main()
{
	string str("Hello Bit.");
	cout << str.size() << ':' << str.capacity() << endl;

	str.reserve(111);
	cout << str.size() << ':' << str.capacity() << endl;

	str.resize(500);
	cout << str.size() << ':' << str.capacity() << endl;

	str.reserve(50);

	cout << str.size() << ":" << str.capacity() << endl;

	return 0;

}

// 以空格为分界分割字符串
int main(int argc, char* argv[])
{
	string strText = "How are you?";
	string strSeparator = " ";
	string strResult;
	int size_pos = 0;
	int size_prev_pos = 0;

	while ((size_pos = strText.find_first_of(strSeparator, size_pos)) != string::npos)
	{
		strResult = strText.substr(size_prev_pos, size_pos - size_prev_pos);

		cout << strResult << " ";

		size_prev_pos = ++size_pos;
	}
	if (size_prev_pos != strText.size())
	{
		strResult = strText.substr(size_prev_pos, size_pos - size_prev_pos);

		cout << strResult << " ";
	}
	cout << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jamo@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值