【设计类】

一、设计并实现几个类,用于打开并读取不同类型的文件内容。要求如下:

  1. 一种类型对应一个类。
  2. 根据文件名后缀区分文件类型。需要支持 .ini, .xml, .json。
  3. 这些类需要支持以下几个方法:
    bool open() - 打开文件
    std::string file() const - 返回打开的文件路径
    std::string get(const std::string& key) - 根据key获取内容(只需简单实现,返回文件类型+首行内容)
  4. 可扩展,能方便添加其他文件类型。
#include <iostream>
#include <fstream>
#include <string>
#include <map>

class FileReader {
public:
	virtual ~FileReader() {}
	virtual bool open(const std::string& filename) = 0;
	virtual std::string file() const = 0;
	virtual std::string get(const std::string& key) = 0;
};

class IniFileReader : public FileReader {
public:
	virtual bool open(const std::string& filename) override {
		file_.open(filename);
		return file_.is_open();
	}

	virtual std::string file() const override {
		return filename_;
	}

	virtual std::string get(const std::string& key) override {
		std::string line;
		while (std::getline(file_, line)) {
			if (line[0] == ';') continue; // ignore comments
			size_t pos = line.find('=');
			if (pos != std::string::npos) {
				std::string k = line.substr(0, pos);
				if (k == key) {
					return "ini: " + line.substr(pos + 1);
				}
			}
		}
		return "";
	}

private:
	std::ifstream file_;
	std::string filename_;
};

class XmlFileReader : public FileReader {
public:
	virtual bool open(const std::string& filename) override {
		file_.open(filename);
		return file_.is_open();
	}

	virtual std::string file() const override {
		return filename_;
	}

	virtual std::string get(const std::string& key) override {
		std::string line;
		while (std::getline(file_, line)) {
			if (line.find("<" + key + ">") != std::string::npos) {
				std::getline(file_, line);
				return "xml: " + line;
			}
		}
		return "";
	}

private:
	std::ifstream file_;
	std::string filename_;
};

class JsonFileReader : public FileReader {
public:
	virtual bool open(const std::string& filename) override {
		file_.open(filename);
		if (file_.is_open()) {
			std::string line;
			std::getline(file_, line);
			if (line[0] == '{') {
				buffer_ = line;
			}
			else {
				file_.close();
				return false;
			}
		}
		filename_ = filename;
		return true;
	}

	virtual std::string file() const override {
		return filename_;
	}

	virtual std::string get(const std::string& key) override {
		if (buffer_.empty()) {
			return "";
		}
		size_t pos = buffer_.find("\"" + key + "\":");
		if (pos == std::string::npos) {
			return "";
		}
		size_t start = buffer_.find(':', pos) + 1;
		size_t end = buffer_.find(',', start);
		if (end == std::string::npos) 
		{
			end = buffer_.find('}', start);
		}
		return "json: " + buffer_.substr(start, end - start);
	}

private:
	std::ifstream file_;
	std::string filename_;
	std::string buffer_;
};

二、实现一个String类,要求:
1、不能使用系统默认构造、析构、拷贝构造、赋值操作符等;
2、实现常用操作接口,如拼接、分隔、字符查找、替换等。

#include<iostream>
using namespace std;

#define MSTRING_NUM_SIZE sizeof(int)//引用计数大小
#define DEFEALT_LEN (10+MSTRING_NUM_SIZE)

class Mstring
{
public:
	Mstring(const char* str)
	{
		if (NULL == str)
		{
			_len = DEFEALT_LEN;
			_val_len = 0;
			_str = new char[_len];
			memset(_str, 0, _len);
			return;
		}

		_val_len = strlen(str);
		_len = _val_len + 1;
		_str = new char[_len];
		memset(_str, 0, _len);
		for (int i = 0; i < _val_len; i++)
		{
			_str[i] = str[i];
		}
	}
	Mstring(const Mstring& src)
	{
		_val_len = strlen(src._str);
		_len = _val_len + 1;
		_str = new char[_len];
		memset(_str, 0, _len);
		for (int i = 0; i < _val_len; i++)
		{
			_str[i] = src._str[i];
		}
	}
	Mstring& operator=(const Mstring& src)
	{
		if (&src == this)
		{
			return *this;
		}
		delete[]_str;

		_val_len = strlen(src._str);
		_len = _val_len + 1;
		_str = new char[_len];
		memset(_str, 0, _len);
		for (int i = 0; i < _val_len; i++)
		{
			_str[i] = src._str[i];
		}
		return *this;
	}
	~Mstring()
	{
		delete[]_str;
	}
	void push_back(char c)//尾插
	{
		if (full())//判满
		{
			revert();//如果满了则扩容
		}
		_str[_val_len] = c;
		_val_len++;
	}
	void pop_back()//尾删
	{
		if (empty())
		{
			return;
		}
		_val_len--;
	}
	char back()const//获取最后一个元素
	{
		if (empty())
		{
			return 0;
		}
		return _str[_val_len - 1];
	}
	char front()const//获取第一个元素 
	{
		if (empty())
		{
			return 0;
		}
		return _str[0];
	}
	bool empty()const
	{
		return _val_len;
	}

	Mstring operator+(const Mstring& str)const//拼接
	{
		char* p;
		int len = _val_len + str._val_len + 1;
		p = new char[len];
		memset(p, 0, len);
		int i = 0;
		for (; i < _val_len; i++)
		{
			p[i] = _str[i];
		}
		for (int j = 0; j < str._val_len; j++, i++)
		{
			p[i] = str._str[j];
		}
		return p;//返回指针会直接构造成一个对象
	}
	Mstring operator+(const char c)const//拼接
	{
		char* p;
		int len = _val_len  + 1;
		p = new char[len];
		memset(p, 0, len);
		int i = 0;
		for (; i < _val_len; i++)
		{
			p[i] = _str[i];
		}
		p[len] = c;
		return p;//返回指针会直接构造成一个对象
	}
	//分隔
	Mstring Str_P(char c)
	{
		Mstring tmp = "";
		if (My_char_find(c) != -1) // 这里是处理按空格分割的数据,如果是其他的分隔符,这里和下一行更改为指定的分割符即可。
		{
			int pos = My_char_find(c);
			
			for (int i = 0; i < _val_len; i++)
			{
				tmp=tmp+_str[i];
			}
		}
		return tmp;
	}
	



	//字符查找
	int  My_char_find(char c)const
	{
		int pos = -1;
		for (int i = 0; i < _val_len; i++)
		{
			if (_str[i] == c)
			{
				pos = i;
				return pos;
			}
		}
		return pos;
	}

	//字符替换
	bool My_char_replace(char c,char re)const//拼接
	{
		for (int i = 0; i < _val_len; i++)
		{
			if (_str[i] == c)
			{
				_str[i] = re;
				return true;
			}
		}
		return false;
	}

	char& operator[](int pos)//返回值为引用的目的就是保证外界可以进行修改
	{
		return _str[pos];
	}

	char operator[](int pos)const
	{
		return _str[pos];
	}

	bool full()const
	{
		return _val_len == _len - 1;
	}

	void revert()
	{
		_len = _len << 1;//左移一位,相当于乘以2

		char* p;
		p = new char[_len];
		memset(p, 0, _len);
		int i = 0;
		for (; i < _val_len; i++)
		{
			p[i] = _str[i];
		}
		delete[]_str;
		_str = p;
	}

	int size()const
	{
		return _val_len;
	}


	friend ostream& operator<<(ostream& out, const Mstring& str)
	{
		int i = 0;
		for (; i < str._val_len; i++)
		{
			out << str._str[i];
		}
		out << endl;
		return out;
	}
	friend istream& operator>>(istream& in, Mstring& str)
	{
		char tmp[1024];
		cin >> tmp;
		str = tmp;
		return in;
	}

private:

	bool full()const;
	void revert();


	char* _str;//堆上申请的空间用来存放数据;能否直接使用浅拷贝-----怎么增加引用计数
	int _len;//空间总大小
	int _val_len;//实际占用空间,实际数据数量
};
  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值