C++——String

目录

一学习string的原因

1.从个人理解角度上:

2从C语言上:

二标准库中的string

1(拷贝)构造和析构

2运算符重载

3迭代器

2查询string的各种数据

5增删查改

6其它操作

三string的模拟实现

3.1成员函数

3.1.1构造函数

3.1.2拷贝构造 

3.1.3析构函数

3.2迭代器

3.3扩容

3.4插入字符(串)

3.4.1append

3.4.2insert

 3.4.3push_back

3.4.4赋值运算符=重载

3.5resize

3.6find

 3.7运算符重载<<,>>

完整源代码


一学习string的原因

1.从个人理解角度上:

在刚开始学习之前,我只知道学习完string在以后的刷题中能提高做题效率,在对字符串的处理string库中也许有对应的接口去实现需求,不用自己去写函数的实现。

但在学string中改变了之前的看法:不仅是要会用接口,而且在理解了接口的底层原理后能更好的去理解,使用它。

总结:使用——明理——扩展

2从C语言上:

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

二标准库中的string

使用string必须用它对应的头文件:#include<string>

在学习接口及其文档的说明,可以到cpulspuls官网中去学习:

cplusplus.com - The C++ Resources Network

1(拷贝)构造和析构

string()     构造string类的空字符串(其中有’\0‘)

string(char* s)   构造的同时进行string的拷贝(支持单参数隐式类型转换)

string(const string& str)     string拷贝构造

string(const string& str , size_t  pos , size_t  len = npos)     进行str子串的获取,pos是子串的起始位置,len是子串的结束位置(没有说明就默认是str的结束位置)

~string()     string的析构

2运算符重载

使string的访问向数组访问数据一样数组名+[]

char& operator[] (size_t pos)     

const char& operator[] (size_t pos) const   

 string类的赋值,对象可以是string,字符串,字符

string& operator = (const string& str)   

string& operator = (const char* s)

string& operator = (char c)

string类字符串的尾插,对象可以是string,字符串,字符

string& operator += (const string& str)

string& operator += (const char*s)

string& operator += (char c)

实现string类与char*,char类型的字符(串)进行拼接(反过来也成立) 

string operator+ (const string& lhs , const char* rhs)

string operator+ (const char* lhs , const string& rhs)

string operator+ (const string& lhs , char rhs)

string operator+ (char rhs ,  const string& lhs)

流插入,流提取的重载

istream& operator >>(istream is , string& str)

ostream& operator <<(ostream os , string& str)

3迭代器

迭代器行为指针一样,但不=指针

iterator begin()     指向string的开始 

const_iterator begin() const   

iterator end()      指向string的末尾

const_iterator end() const

反向迭代器

iterator rbegin()     指向string的末尾

irerator rend()        指向string的开始

有了迭代器,我们就有了两种遍历string的方式:迭代器与范围for(本质是迭代器)

#include<string>
int main()
{
	string s1("hello warld");
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << ' ';
		it++;
	}
	cout << endl;
	for (auto ch : s1)
	{
		cout << ch << ' ';
	}
	cout << endl;
	return 0;
}

2查询string的各种数据

size_t size() const     返回string内的字符个数(不包含’\0‘)      =size_t length() const

size_t capacity() const     返回string的空间大小(包含’\0‘)

void reserve(size_t n=0)   开n个空间大小

(知道要插入的多少数据提前开好空间就不用进行扩容,提高了效率)

(但空间不够时,string应该要进行对应的空间扩容。那么是要扩容多少呢?2倍扩?

我们用+=的方式在string末尾每次插入一个字符,循环100次来观察capacity的变化:

#include<string>
int main()
{
	string s;

	size_t sz = s.capacity();
	cout << "capacity changed: " << sz << '\n';
	cout << "making s grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		s += ('c');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
	return 0;
}

在VS底层中实现的扩容:先开出15内存空间,等到空间不够时,第一次扩容是2倍扩,接下来的扩容都是大概按1.5来扩容。

而在g++下的扩容全是按照2倍扩容来的:

但两者的扩容方式不同会不会有什么影响呢?

没有!! 2倍扩容也好1.5倍扩容也好,说到底它们的目标都是要进行扩容。实现起来的细节是不做考虑的。


void resize(size_t n,char c)     开n个空间大小并插入n-size()个字符c

resize一般不缩容,在以下的不同情况使用resize会有不同的效果:

5增删查改

viod push_back (char c)     在string的末尾插入一个字符

void pop_back (char c)       在string的末尾删除一个字符        

string& insert(size_t pos , char c)     在pos下插入字符(字符串,string)

string& erase(size_t pos , size_t len = npos)     在pos位置下删除len个字符(不加len默认删除pos后面的全部字符)  (左闭右开)

void swap(string& str)   不仅仅是数据的交换,还有size,capacity的交换

6其它操作

void swap(string& x , string& y)     与算法库的swap分离开(如果调用算法库的swap,三次拷贝+一次析构代价太大)

const char* c_str() const     类型转换成char*方便打印(string类的要用到运算符重载)

string substr(size_t pos = 0 , size_t len = npos)     从pos位置到len个位置的字符串截取

size_t find(char c , size_t pos=0)   返回字符c所在的下标

string& replace(size_t pos , size_t len = npos , char c)     在pos到len的位置插入c字符

两者的特性结合可用来解决:

字符串空格的替换

三string的模拟实现

在string类中共有三个成员:_str(字符串),_size(字符个数),_capacity(空间大小)

其中,_size个数不包含‘\0’,但在_capacity中要多开出一个空间存储‘\0’!!

3.1成员函数

3.1.1构造函数

在实现构造时,如果string构造不传参,默认为空串。

但不意味着给缺省值时就是”\0“,因为写成”“是有’\0‘的存在的

//string(const char* str = "\0")
string(const char* str = "")
	:_size(strlen(str))
{
	_capacity = _size;
	_str = new char[_size + 1];
	strcpy(_str, str);//把字符串拷贝给_str成员对象

}

3.1.2拷贝构造 

 拷贝构造里不单单只是数据拷贝!要在拷贝之前先new一块跟str一样长的空间,在进行数据的拷贝。也就是所谓的深拷贝!

一般的思路是:直接开出一个与拷贝对象一样长的空间,再把对应的数据赋值过去就完事了

string(const string& str)
{
	_str = new char[str._capacity + 1];
	strcpy(_str, str._str);
	_size = str._size;
	_capacity = str._capacity;
}

但这种属于是’自己买菜自己做‘。是比较传统的写法。

有这样的写法:构造一个与拷贝对象一样的临时对象,在进行交换(深拷贝),比较方便简洁:

string(const string& str)
{
	string tmp(str.c_str());
	swap(tmp);
}

 有了拷贝构造,与它对应的还有一个赋值运算符的重载:也是类似的道理:

string& operator=(const string& str)
{
	char* tmp = new char[str._capacity + 1];
	strcpy(tmp, str._str);

	delete[] _str;//释放
	_str = tmp;
	_size = str._size;
	_capacity = str._capacity;
    return *this;
}

//现代写法
string& operator=(const string& str)
{
	string tmp(str.c_str());
	swap(tmp);
    return *this;
}

string& operator=(string ss)
{    
    swap(ss);
    return *this;
}

3.1.3析构函数

~string()
{
	delete[] _str;
	_str = nullptr;
	_size = _capacity = 0;
}

3.2迭代器

实现的迭代器因为要支持可读可写与只读两个版本,实现时要实现俩个版本出来:

对应的begin(),end()实现成string类中的成员函数

typedef char* iterator;//类似指针的作用
typedef const char* const_iterator;
const_iterator begin() const
{
	return _str;
}
const_iterator end() const
{
	return _str + _size;
}

iterator begin()
{
	return _str;
}
iterator end()
{
	return _str + _size;
}

3.3扩容

传参进来的n如果比_capacity要小则需要进行空间的扩容到n+1(’\0‘要开给它):

void reserve(size_t n)
{
	//扩容
	if (_capacity < n)
	{
		char* tmp = new char[n + 1];
		strcpy(tmp , _str);
		_str = tmp;
		_capacity = n;
	}
}

它的扩容不是我们在C语言学的函数realloc扩容那样有两种情况:原地扩与异地扩。它的扩容就是直接看出一块新的空间,在把_str的数据拷贝的! 

3.4插入字符(串)

3.4.1append

将原来的_capacity与拼接形成新的string的_size个数进行比较,空间不够才进行扩容:

void append(const char* s)
{
	size_t len = strlen(s);
	//扩容
	if (_capacity < _size + len)
	{
		reserve(_size + len);
	}
	/*for (size_t i = _size; i < len; i++)
	{
		_str[i] = *s;
		s++;
	}*/
	strcpy(_str +_size, s);
	_size += len;
}

3.4.2insert

在pos位置上插入字符也好,字符串也好,都需要进行是否扩容与数据挪动,字符串的挪动必须是从后往前进行字符串的覆盖:

void insert(size_t pos, char ch)
{
	assert(pos <= _size);
	if (_capacity == _size)
	{
		//扩容
		reserve(_capacity == 0 ? 4 : _capacity * 2);
	}
    size_t end=_size;
	while (end>=pos)
	{
		_str[end+1] = _str[end];
		end--;
	}
	_str[pos] = ch;
	_size += 1;
}

但在这有个细节:如果pos的位置是0即进行头插,这将会进行程序出现问题:因为但end=0循环进入,end--使得end=-1。但end的类型是size_t,不会为负数!修改方式有两种:

1修改类型;2让end=_size+1进行循环时end永远都>pos:

	void insert(size_t pos, char ch)
	{
		assert(pos <= _size);
		if (_capacity == _size)
		{
			//扩容
			reserve(_capacity == 0 ? 4 : _capacity * 2);
		}
        1
		size_t end = _size;//当pos=0时,size_t end=0,end--!=-1
		int end = _size;
		while (end >= (int)pos)
		{
			_str[end + 1] = _str[end];
			end--;

        2
		size_t end = _size + 1;
		while (end>pos)
		{
			_str[end] = _str[end - 1];
			end--;
		}

		_str[pos] = ch;
		_size += 1;
	}

插入的是字符串也是同理的:

		void insert(size_t pos, const char* str)
		{
			size_t len = strlen(str);
			assert(pos <= _size);
			if (_capacity <= _size + len)
			{
				//扩容
				reserve(_size + len);
			}
			/*int end = _size;
			while (end >= (int)pos)
			{
				_str[end + len] = _str[end];
				end--;
			}*/
			size_t end = _size + len;
			while (end > pos+len-1)
			{
				_str[end] = _str[end-len];
				end--;
			}
			strncpy(_str+pos, str, len);
			_size += len;
		}

 3.4.3push_back

复用insert进行尾插或者直接实现:

void push_back(char ch)
{
	if (_capacity == _size)
	{
		reserve(_capacity == 0 ? 4 : _capacity * 2);
	}
	_str[_size++] = ch;
	_str[_size] = '\0';
	//insert(_size, ch);
}

3.4.4赋值运算符=重载

string& operator+=(char ch)
{
	push_back(ch);
	return *this;
}
string& operator+=(const char* str)
{
	append(str);
	return *this;
}

3.5resize

实现resize是要了解的是:使用resize一般不缩容。要插入n个字符是有两种情况:n<=_size是仅需保留前n个字符串后加’\0‘即可;n>_capacity就要进行扩容与插入n-_size个字符:

		void resize(size_t n, char ch = npos)
		{
			if (n <= _size)
			{
				_str[n] = '\0';
				_size = n;
			}
			else
			{
				//扩容
				reserve(n);//n>size后面有要求加字符
				for (size_t i = _size; i < n; i++)
				{
					_str[i] = ch;
				}
				_str[n] = '\0';
				_size = n;
			}
		}

对应resize与reserve:基本上都是有扩容的功能的,但resize能在进行扩容的基础上将数据进行初始化,比较适合在对数据的管理上使用它。

3.6find

进行string的遍历,如果找到该字符就返回该字符的下标:如果是找字符串,找到了就返回该字符串的起始位置:

size_t find(char c, size_t pos = 0) const
{
	assert(pos < _size);
	for (size_t i = pos; i < _size; i++)
	{
		if (c == _str[i])
		{
			return i;
		}
	}
	return npos;
}
size_t find(const char* s, size_t pos = 0) const
{
	assert(pos < _size);
	const char* p=strstr(_str + pos, s);
	if(p)
	{
		return p - _str;//指针-指针=s的下标
	}
	else
	{
		return npos;
	}
}

 3.7运算符重载<<,>>

流提取或者是流插入重载成全局函数好方便调用:

ostream& operator<< (ostream& os, const string& str)
{
	for (int i = 0; i < str.size(); i++)
	{
		os << str[i];
	}
	return os;
}

istream& operator>>(istream& in, string& s)
{
	s.clear();//防止string中有数据影响流插入
	char ch;
	//in >> ch;
	ch = in.get();
	//s.reserve(128);
	while (ch != '\n' && ch != ' ')
	{
		s += ch;
		ch = in.get();
	}

	return in;
}

在重载流插入时,如果按照上面的实现方式的话,在每次插入时都要进行扩容,非常影响程序运行的效率。

如果要进行reserve开空间,但至于要看多少不能确定。所以就有人进行对这段代码的优化: 

istream& operator>>(istream& in, string& s)
{
	s.clear();

	char ch;
	//in >> ch;
	ch = in.get();
	char buff[128];
	size_t i = 0;
	while (ch != ' ' && ch != '\n')
	{
		buff[i++] = ch;
		// [0,126]
		if (i == 127)
		{
			buff[127] = '\0';
			s += buff;
			i = 0;
		}

		ch = in.get();
	}

	if (i > 0)
	{
		buff[i] = '\0';
		s += buff;
	}

	return in;
}

要不要扩容取决于会不会超出buff的数组总个数,非常的妙!!!

完整源代码

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<assert.h>
#include<iostream>
using namespace std;
namespace bit
{
	class string
	{
	public:
		//迭代器
		typedef char* iterator;//类似指针的作用
		typedef const char* const_iterator;
		const_iterator begin() const
		{
			return _str;
		}
		const_iterator end() const
		{
			return _str + _size;
		}

		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}

		//在末尾加n个ch字符
		void resize(size_t n, char ch = npos)
		{
			if (n <= _size)
			{
				_str[n] = '\0';
				_size = n;
			}
			else
			{
				//扩容
				reserve(n);//n>size后面有要求加字符
				for (size_t i = _size; i < n; i++)
				{
					_str[i] = ch;
				}
				_str[n] = '\0';
				_size = n;
			}
		}

		//先开空间
		void reserve(size_t n)
		{
			//扩容
			if (_capacity < n)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				_str = tmp;
				_capacity = n;
			}
		}

		//末尾插人字符
		void push_back(char ch)
		{
			if (_capacity == _size)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}
			_str[_size++] = ch;
			_str[_size] = '\0';
			//insert(_size, ch);
		}
		//末尾插入字符串
		void append(const char* s)
		{
			size_t len = strlen(s);
			//扩容
			if (_capacity < _size + len)
			{
				reserve(_size + len);
			}
			/*for (size_t i = _size; i < len; i++)
			{
				_str[i] = *s;
				s++;
			}*/
			strcpy(_str +_size, s);
			_size += len;
		}
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		string& operator+=(const char* str)
		{
			append(str);
			return *this;
		}

		//在pos位置插入字符
		void insert(size_t pos, char ch)
		{
			assert(pos <= _size);
			if (_capacity == _size)
			{
				//扩容
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}
			//size_t end = _size;//当pos=0时,size_t end=0,end--!=-1
			/*int end = _size;
			while (end >= (int)pos)
			{
				_str[end + 1] = _str[end];
				end--;
			}*/
			size_t end = _size + 1;//size-1X
			while (end>pos)
			{
				_str[end] = _str[end - 1];
				end--;
			}
			_str[pos] = ch;
			_size += 1;
		}
		void insert(size_t pos, const char* str)
		{
			size_t len = strlen(str);
			assert(pos <= _size);
			if (_capacity <= _size + len)
			{
				//扩容
				reserve(_size + len);
			}
			/*int end = _size;
			while (end >= (int)pos)
			{
				_str[end + len] = _str[end];
				end--;
			}*/
			size_t end = _size + len;
			while (end >= pos+len)
			{
				_str[end] = _str[end-len];
				end--;
			}
			strncpy(_str+pos, str, len);
			_size += len;
		}

		//删除pos位置的字符
		void erase(size_t pos, int len = npos)
		{
			assert(pos <= _size);
			if (len == npos || len >= _size - pos)//len+pos会溢出
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				strcpy(_str + pos, _str + pos + len);
				_size -= len;
			}
		}

		//string(const char* str = "\0")
		string(const char* str = "")
			:_size(strlen(str))
		{
			_capacity = _size;
			_str = new char[_size + 1];
			strcpy(_str, str);//把字符串拷贝给_str成员对象

		}

		//传统写法
		//s2(s1)
		//string(const string& str)
		//{
		//	_str = new char[str._capacity + 1];
		//	strcpy(_str, str._str);
		//	_size = str._size;
		//	_capacity = str._capacity;
		//}
		//s2=s1
		//string& operator=(const string& str)
		//{
		//	char* tmp = new char[str._capacity + 1];
		//	strcpy(tmp, str._str);

		//	delete[] _str;//置空
		//	_str = tmp;
		//	_size = str._size;
		//	_capacity = str._capacity;
		// return *this;
		//}

		//现代写法
		string(const string& str)
		{
			string tmp(str.c_str());
			swap(tmp);
		}
		string& operator=(string str)
		{
			swap(str);
			return *this;
		}

		~string()
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0;
		}

		const char* c_str() const
		{
			return _str;
		}
		size_t size() const
		{
			return _size;
		}
		size_t capacity() const
		{
			return _capacity;
		}
		char& operator[](size_t pos)
		{
			assert(pos <= _size);
			return _str[pos];
		}
		const char& operator[](size_t pos) const
		{
			assert(pos <= _size);
			return _str[pos];
		}

		void clear()
		{
			_size = 0;
			_str[_size] = '\0';
		}

		//string的成员函数
		void swap(string& str)
		{
			//共有三种swap使用:算法,string.swap,swap
			std::swap(_str, str._str);
			std::swap(_size, str._size);
			std::swap(_capacity, str._capacity);
		}

		bool empty()const
		{
			if (_size == 0)
			{
				return true;
			}
			return false;
		}

		size_t find(char c, size_t pos = 0) const
		{
			assert(pos < _size);
			for (size_t i = pos; i < _size; i++)
			{
				if (c == _str[i])
				{
					return i;
				}
			}
			return npos;
		}
		size_t find(const char* s, size_t pos = 0) const
		{
			assert(pos < _size);
			const char* p=strstr(_str + pos, s);
			if(p)
			{
				return p - _str;//指针-指针=s的下标
			}
			else
			{
				return npos;
			}
		}

		string substr(size_t pos = 0, size_t len = npos) const
		{
			string s;
			if (len >= _size-pos)
			{
				for (size_t i = pos; i < _size; i++)
				{
					s += _str[i];
				}
			}
			else
			{
				for (size_t i = pos; i < pos + len; i++)
				{
					s += _str[i];
				}
			}
			return s;
		}

	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	public:
		static const int npos;//类中共有的对象
	};
	const int string::npos = -1;

	bool operator==(const string& s1,const string& s2)
	{
		return strcmp(s1.c_str(), s2.c_str()) == 0;
	}
	bool operator<(const string& s1, const string& s2)
	{
		return strcmp(s1.c_str(), s2.c_str()) < 0;
	}
	bool operator>(const string& s1, const string& s2)
	{
		return !(strcmp(s1.c_str(), s2.c_str()) == 0 || strcmp(s1.c_str(), s2.c_str()) < 0);
	}

	//重载成全局函数
	ostream& operator<< (ostream& os, const string& str)
	{
		for (int i = 0; i < str.size(); i++)
		{
			os << str[i];
		}
		return os;
	}
	istream& operator>> (istream& is, string& str)//getline的实现方式	
	{
		str.clear();
		char ch = is.get();
		char buffer[128];
		size_t i = 0;
		while (ch != ' ' && ch != '\n')
		{
			//str += ch;
			buffer[i++] = ch;
			if (i == 127)
			{
				buffer[127] = '\0';
				//开128个空间
				str += buffer;
				//重新计算
				i = 0;
			}
			ch = is.get();
		}
		if (i > 0)
		{
			//有多少看多少
			buffer[i] = '\0';
			str += buffer;
		}
		return is;
	}
	/*istream& operator>> (istream& is, string& str)
	{
		str.clear();
		char ch = is.get();
		while(ch != ' ' && ch != '\n')
		{
			str += ch;
			ch = is.get();
		}
		return is;
	}*/

	//定义一个全局的swap就不会去调用算法的swap
	void swap(string& s1,string& s2)
	{
		s1.swap(s2);
	}

  • 14
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的C++文字RPG游戏的示例代码,其中包括了基本的角色、战斗和物品系统: ```c++ #include <iostream> #include <string> #include <cstdlib> #include <ctime> using namespace std; // 角色类 class Character { public: string name; int hp; int atk; int def; int gold; Character(string n, int h, int a, int d, int g) { name = n; hp = h; atk = a; def = d; gold = g; } // 攻击函数 void attack(Character& other) { int damage = atk - other.def; if (damage < 0) { damage = 0; } other.hp -= damage; cout << name << "攻击了" << other.name << ",造成了" << damage << "点伤害。" << endl; } // 是否死亡 bool isDead() { return hp <= 0; } }; // 物品类 class Item { public: string name; int price; int hp; int atk; int def; Item(string n, int p, int h, int a, int d) { name = n; price = p; hp = h; atk = a; def = d; } }; // 商店类 class Shop { public: Item items[3]; Shop() { items[0] = Item("草药", 10, 20, 0, 0); items[1] = Item("铁剑", 50, 0, 10, 0); items[2] = Item("铁甲", 100, 0, 0, 10); } // 显示商店物品 void showItems() { cout << "欢迎光临!以下是本店的物品:" << endl; for (int i = 0; i < 3; i++) { cout << i + 1 << ". " << items[i].name << " - " << items[i].price << "金币" << endl; } } // 购买物品 bool buy(Character& c, int choice) { if (c.gold < items[choice - 1].price) { cout << "金币不足,法购买!" << endl; return false; } c.gold -= items[choice - 1].price; c.hp += items[choice - 1].hp; c.atk += items[choice - 1].atk; c.def += items[choice - 1].def; cout << "购买成功!" << endl; return true; } }; // 战斗函数 void battle(Character& player, Character& enemy) { cout << "你遇到了一只" << enemy.name << ",准备战斗!" << endl; while (!player.isDead() && !enemy.isDead()) { player.attack(enemy); if (enemy.isDead()) { cout << enemy.name << "被你打败了!" << endl; player.gold += enemy.gold; return; } enemy.attack(player); if (player.isDead()) { cout << "你被" << enemy.name << "打败了!" << endl; return; } } } int main() { srand(time(NULL)); // 初始化随机数种子 // 初始化角色和商店 Character player("勇者", 100, 10, 5, 50); Character enemies[3] = { Character("史莱姆", 30, 5, 2, 10), Character("骷髅兵", 50, 10, 5, 20), Character("巨龙", 100, 20, 10, 50) }; Shop shop; // 游戏循环 while (true) { cout << "你的状态 - HP:" << player.hp << " ATK:" << player.atk << " DEF:" << player.def << " 金币:" << player.gold << endl; cout << "请选择操作:" << endl; cout << "1. 进入商店" << endl; cout << "2. 进行战斗" << endl; cout << "3. 离开游戏" << endl; int choice; cin >> choice; switch (choice) { case 1: shop.showItems(); cout << "请选择要购买的物品(输入编号):" << endl; cin >> choice; shop.buy(player, choice); break; case 2: battle(player, enemies[rand() % 3]); break; case 3: cout << "游戏结束,欢迎再次光临!" << endl; return 0; default: cout << "无效的操作!" << endl; break; } } return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值