string容器

构造和析构

void testOne()
{
	cout << "显示string中字符数组的最大长度" << endl;
	cout << "string::npos  " <<string::npos << endl;
	
	//string类有七个构造函数(C++11新增了两个):
	//	1)string(); // 创建一个长度为0的string对象(默认构造函数)。
	cout << "1-------------" << endl;
	string s1;
	cout << "s1 = " << s1 << endl;
	cout << "s1.capacity()= " << s1.capacity() << endl;
	cout << "s1.size()= " << s1.size() << endl;
	cout << "显示首地址" << endl;
	cout << (void*)*s1.c_str() << endl;
	cout << endl;
	s1 = "hello ! my name is wangjianlin";
	cout << "s1 = " << s1 << endl;
	cout << "s1.capacity()= " << s1.capacity() << endl;
	cout << "s1.size()= " << s1.size() << endl;
	cout <<"显示不同的字符: " << endl;
	cout << *s1.c_str() << endl;
	cout << *(s1.c_str()+1) << endl;
	cout << *(s1.c_str() + 2) << endl;
	cout << "显示首地址" << endl;
	cout << (void*)*s1.c_str() << endl;
	//2)string(const char* s); // 将string对象初始化为s指向的NBTS(转换函数)。
	cout << "2-------------" << endl;
	string s2("hello word 1");
	cout << "s2 =" << s2 << endl;
	string s3 = "hello word 2";
	cout << "s3 = " << s3 << endl;
	//3)string(const string & str); // 将string对象初始化为str(拷贝构造函数)。
	cout << "3-------------" << endl;
	string s4(s2);
	cout << "s4 =" << s4 << endl;
	string s5 = s3;
	cout << "s5 = " << s5 << endl;
	
	//4)string(const char* s, size_t n); // 将string对象初始化为s指向的地址后n字节的内容。
	cout << "4-------------" << endl;
	string s6("hello word4", 3);
	cout << "s6 = " << s6 << endl;
	string s7("hello word4", 30);
	cout << "s7 = " << s7 << endl;

	//5)string(const string & str, size_t pos = 0, size_t n = npos); // 将sring对象初始化为str从位置pos开始到结尾的字符(或从位置pos开始的n个字符)。
	cout << "5-------------" << endl;
	string s8(s3, 3, 5);
	cout << "s8 = " << s8 << endl;
	string s9(s3, 3);
	cout << "s9 = " << s9 << endl;
	cout << "s9.capacity() = " << s9.capacity() << endl;
	cout << "s9.size() = " << s9.size() << endl;

	//6)template<class T> string(T begin, T end); // 将string对象初始化为区间[begin,end]内的字符,其中begin和end的行为就像指针,用于指定位置,范围包括begin在内,但不包括end。

	
	//7)string(size_t n, char c); // 创建一个由n个字符c组成的string对象。
	//析构函数~string()释放内存空间。
	cout << "7-------------" << endl;
	string s12(8, 'x');
	cout << "s12 = " << s12 << endl;
	cout << "s12.capacity() = " << s12.capacity() << endl;
	cout << "s12.size() = " << s12.size() << endl;
	string s13(30, 0);
	cout << "s13 = " << s13 << endl;
	cout << "s13.capacity() = " << s13.capacity() << endl;
	cout << "s13.size() = " << s13.capacity() << endl;

	//	C++11新增的构造函数:
	//	1)string(string && str) noexcept:它将一个string对象初始化为string对象str,并可能修改str(移动构造函数)。

	
	//	2)string(initializer_list<char> il):它将一个string对象初始化为初始化列表il中的字符。

}

在这里插入图片描述

string容器的设计目标

c++申请内存空间的本质

string类的两种用途:

  1. 用作字符串
  2. 用作存放数据的容器

对第4个构造函数再次理解:

4string(const char *s,size_t n); // 将string对象初始化为s指向的地址后n字节的内容。

参数的本质和append一致

string &append(const char *s,size_t n); // 将s指向的地址后n字节的内容连接到当前容器。( 任意数据类型 )

实例:让string存储结构体数据

void testTwo2()
{
	struct st_girl {   // 超女结构体。
		int    bh;
		char name[30];
		bool yz;
		double weight;
		string memo;
	} girl;
	cout << "超女结构体的大小:" << sizeof(struct st_girl) << endl;
	string buffer;  // 创建一个空的string容器buffer。
	for (int i = 0; i < 10; i++) {
		//将超女结构体的内存值置为 0
		memset(&girl, 0, sizeof(struct st_girl));
		//开始对结构体赋值
		girl.bh = i;
		sprintf_s(girl.name, "王健林%d", i);
		girl.yz = true;
		girl.weight = 50 + i;
		girl.memo = "大家好才是真的好! ";
		// 把超女结构追加到buffer中。
		buffer.append((char*)&girl,sizeof(st_girl));
	}
	cout << "buffer.capacity()=" << buffer.capacity() << endl;  // 显示容量。
	cout << "buffer.size()=" << buffer.size() << endl;  // 显示实际大小。

	 // 用一个循环,把buffer容器中全部的数据取出来。
	for (int ii = 0; ii < buffer.size() / sizeof(struct st_girl); ii++)
	{
		memset(&girl, 0, sizeof(struct st_girl));  // 初始化超女结构体。

		// 把容器中的数据复制到超女结构体。
		memcpy(&girl, buffer.data() + ii * sizeof(struct st_girl), sizeof(struct st_girl));
		// buffer.copy((char*)&girl, sizeof(struct st_girl), ii * sizeof(struct st_girl));

		// 显示超女结构体成员的值。
		cout << "bh=" << girl.bh << ",name=" << girl.name << ",yz=" << girl.yz << ",weight="
			<< girl.weight << ",memo=" << girl.memo << endl;
	}
}

在这里插入图片描述

其实,在这里:buffer.append()函数的参数和第4个构造函数是相同的。
使用char *s的好处是:

  1. 可以接受不同的数据类型,存储在string中(存储的时候地址需要强转一下)
    (char*)&girl,sizeof(st_girl)
  2. 使用数据的时候,在按照数据长度转到相应的数据类型
    memcpy(&girl, buffer.data() + ii * sizeof(struct st_girl), sizeof(struct st_girl));

strinf容器的操作

特性操作

size_t max_size() const;    // 返回string对象的最大长度string::npos,此函数意义不大。
size_t capacity() const;     // 返回当前容量,可以存放字符的总数。
size_t length() const;      // 返回容器中数据的大小(字符串语义)。
size_t size() const;         // 返回容器中数据的大小(容器语义)。
bool empty() const;     // 判断容器是否为空。
void clear();             // 清空容器。
void shrink_to_fit();	      // 将容器的容量降到实际大小(需要重新分配内存)。
void reserve( size_t size=0);  // 将容器的容量设置为至少size。
void resize(size_t len,char c=0);  // 把容器的实际大小置为len,如果len<实际大小,会截断多出的部分;如果len>实际大小,就用字符c填充。

字符操作

char &operator[](size_t n); 
const char &operator[](size_t n) const;  // 只读。
char &at(size_t n); 
const char &at(size_t n) const;          // 只读。
operator[]at()返回容器中的第n个元素,但at函数提供范围检查,当越界时会抛出out_of_range异常,operator[]不提供范围检查。
const char *c_str() const; // 返回容器中动态数组的首地址,语义:寻找以null结尾的字符串。
const char *data() const; // 返回容器中动态数组的首地址,语义:只关心容器中的数据。
int copy(char *s, int n, int pos = 0) const; // 把当前容器中的内容,从pos开始的n个字节拷贝到s中,返回实际拷贝的数目。

string和char*相互转换
使用copy函数的例子:

	string a("hello");
	cout << a.max_size() << endl;
	a.reserve(100);
	cout << a.max_size() << endl;
	cout << a.at(2) << endl;
	cout<<a[0]<<endl;
	a.at(2) = 'x';
	cout << a << endl;
	cout << (char*)a.c_str() << endl;
	cout << "-----------" << endl;
	string b="xxxxx";
	cout << (char*)b.data() << endl;
	cout << a.copy((char*)b.c_str(), 3, 0) << endl;
	cout << b << endl;
	cout << "---" << endl;

在这里插入图片描述
赋值操作

1)string &operator=(const string &str); // 把容器str赋值给当前容器。
2)string &assign(const char *s); // 将string对象赋值为s指向的NBTS。
3)string &assign(const string &str); // 将string对象赋值为str。
4)string &assign(const char *s,size_t n); // 将string对象赋值为s指向的地址后n字节的内容。
5)string &assign(const string &str,size_t pos=0,size_t n=npos); // 将sring对象赋值为str从位置pos开始到结尾的字符(或从位置pos开始的n个字符)。

连接操作

1)string &operator+=(const string &str); //把容器str连接到当前容器。
2)string &append(const char *s); // 把指向s的NBTS连接到当前容器。
3)string &append(const string &str); // 把容器str连接到当前容器。
4)string &append(const char *s,size_t n); // 将s指向的地址后n字节的内容连接到当前容器。
5)string &append(const string &str,size_t pos=0,size_t n=npos); // 将str从位置pos开始到结尾的字符(或从位置pos开始的n个字符)连接到当前容器。

交换操作

void swap(string &str);    // 把当前容器与str交换。

如果数据量很小,交换的是动态数组中的内容,如果数据量比较大,交换的是动态数组的地址。

截取操作

string substr(size_t pos = 0,size_t n = npos) const; // 返回pos开始的n个字节组成的子容器。

之后的比较,查找,替换,删除都是string用作字符串。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值