C++重写String类

基于STL模板库及侯捷的源码剖析。全部代码都已经过测试检验。

头文件:_string.h

#ifndef _STRING_H_
#define _STRING_H_
#include <iostream>
#include <fstream>
using std::cout;
using std::cin;
using std::endl;
using std::ostream;
using std::istream;

class String
{
private:
	char* m_str;
	int m_length;
public:
	String(const char*str=NULL);   //默认构造
	String(const String& another); //拷贝构造
	~String();  //析构函数
	String& operator = (const String& another);  //重载“=”
	String operator + (const String& another);  //重载“+”
	String substr(int start, int end);   //求限定范围子串
	String removeSpaces();  //消除字符串中的空格
	String removeChar(const char& ch);  //消除字符串中的指定字符
	String insert(int index, char letter);  //在指定字符串的指定位置添加某字符
	String insert(int index, char* letter);  //在指定字符串指定位置添加字符串
	String insert(int index, String letter);  //在指定字符串指定位置添加字符串
	String reverse();  //字符串翻转

	bool operator > (const String& another);  //重载“>”
	bool operator < (const String& another);  //重载“<”
	friend ostream & operator <<(ostream& out, const String& another);  //重载“<<”
	friend istream & operator >>(istream& in, String& another);    //重载“>>”
	bool operator == (const String& another);  //重载“==”
	char& operator[](int idx);  //重载运算符“[]”
	void clear();  //字符串初始化(地址不变)
	void toUpperCase();    //小写转大写
	void toLowerCase();    //大写转小写
	void exchange(String& another);  //与目标字符串互换内容
	int find(String s);   //查找字符串
	int find(char* s);   //查找字符串
	void display();  //屏幕输出字符串

	//与文件有关的操作(当前目录下的String.txt)
	String read(char* filename);  //从文件读取字符串
	void write(char* title, String text);  //内容写入文件
	void writeCopy();  //将字符串复制写入文件
	void writeConnect(const String& another);  //字符串连接后写入文件
	void writeSubstr(int start, int end);  //将限定范围内子串写入文件
	void writeRemoveSpaces();   //消除字符串中的空格并写入文件
	void writeRemoveChar(const char& ch);  //消除字符串中指定字符并写入文件
	void writeInsert(int index, char letter);  //字符串指定位置添加字符并写入文件
	void writeInsert(int index, char* letter);  //字符串指定位置添加字符串并写入文件
	void writeInsert(int index, String letter);  //字符串指定位置添加字符串并写入文件
	void writeReverse();  //字符串翻转并写入文件
	void writeClear();   //文件清空
	void writeToUpperCase();  //字符串小写转大写并写入文件
	void writeToLowerCase();  //字符串大写转小写并写入文件
};

#endif  //_STRING_H_

实现文件:_string.cpp

#include "_string.h"

//内容写入文件
void String::write(char* title, String text)
{
	std::ofstream file("String.txt");
	if (!file.is_open())
		cout << "no open!\n";
	file << title << text.m_str << "\n\n";
	file.close();
}

//默认构造函数
String::String(const char* str)
{
	if (str == NULL)
	{
		m_str = new char[1];
		*m_str = '\0';
		m_length = 0;
	}
	else
	{
		m_length = strlen(str);
		m_str = new char[m_length + 1];
		strcpy_s(m_str, m_length + 1, str);
	}
}

//拷贝构造
String::String(const String& another)
{
	m_length = another.m_length;
	m_str = new char[m_length + 1];
	strcpy_s(m_str, m_length + 1, another.m_str);
}

//析构函数
String::~String()
{
	delete[]m_str;
	m_str = NULL;
	cout << this << "已析构" << endl;
}

//重载运算符=
String& String::operator=(const String& another)
{
	if (this == &another)   //防止出现自赋值
		return *this;
	delete[] this->m_str;     //先删除自己的空间
	m_length = another.m_length;
	m_str = new char[m_length + 1];
	strcpy_s(m_str, m_length + 1, another.m_str);
	return *this;
}

//重载运算符+
String String::operator+(const String& another)
{
	String tmp; //tmp=this+another
	tmp.m_length = this->m_length + another.m_length;
	delete[] tmp.m_str;
	tmp.m_str = new char[tmp.m_length + 1];
	memset(tmp.m_str, 0, tmp.m_length + 1);
	strcat_s(tmp.m_str, this->m_length + 1, this->m_str);
	strcat_s(tmp.m_str, tmp.m_length + 1, another.m_str);
	return tmp;
}

//求限定范围子串
String String::substr(int start, int end)
{
	String tmp;
	tmp.m_length = end - start + 1;
	delete[] tmp.m_str;
	tmp.m_str = new char[tmp.m_length + 1];
	int i = start; //初始化为所求子串在父串的初始位置
	int j = 0;  //递增变量
	while (i <= end)
		tmp.m_str[j++] = this->m_str[i++];
	tmp.m_str[j] = '\0';
	return tmp;
}

//消除屏幕中的空格
String String::removeSpaces()
{
	String tmp;
	if (this->m_length == 0) return tmp;
	tmp.m_length = this->m_length;
	tmp.m_str = new char[tmp.m_length + 1];
	int j = 0;
	for (int i = 0; this->m_str[i] != '\0'; )
	{
		if (this->m_str[i] == ' ')
		{
			i++;
			tmp.m_length--;
			continue;
		}
		else
			tmp.m_str[j++] = this->m_str[i++];
	}
	tmp.m_str[j] = '\0';
	return tmp;
}

//消除字符串中的指定字符
String String::removeChar(const char& ch)
{
	String tmp;
	if (this->m_length == 0) return tmp;
	tmp.m_length = this->m_length;
	tmp.m_str = new char[tmp.m_length + 1];
	int j = 0;
	for (int i = 0; this->m_str[i] != '\0'; )
	{
		if (this->m_str[i] == ch)
		{
			i++;
			tmp.m_length--;
			continue;
		}
		else
			tmp.m_str[j++] = this->m_str[i++];
	}
	tmp.m_str[j] = '\0';
	return tmp;
}

//在指定字符串的指定位置添加某字符
String String::insert(int index, char letter)
{
	String tmp;
	tmp.m_length = this->m_length + 1;
	tmp.m_str = new char [tmp.m_length+1];
	int i = 0;
	for (;i<index;i++)
		tmp.m_str[i] = this->m_str[i];
	tmp.m_str[i++] = letter;
	for (; i < tmp.m_length; i++)
		tmp.m_str[i] = this->m_str[i - 1];
	tmp.m_str[i] = '\0';
	return tmp;
}

//在指定字符串指定位置添加字符串
String String::insert(int index, char* letter)
{
	int len = strlen(letter);
	String tmp;
	tmp.m_length = this->m_length + len;
	tmp.m_str = new char[tmp.m_length + 1];
	int i = 0;
	for (; i < index; i++)
		tmp.m_str[i] = this->m_str[i];
	for (int j = 0; j < len; j++)
		tmp.m_str[i + j] = letter[j];
	i = i + len;
	for (; i < tmp.m_length; i++)
		tmp.m_str[i] = this->m_str[i - len ];
	tmp.m_str[i] = '\0';
	return tmp;
}

//在指定字符串指定位置添加字符串
String String::insert(int index, String letter)
{
	String tmp;
	tmp.m_length = this->m_length + letter.m_length;
	tmp.m_str = new char[tmp.m_length + 1];
	int i = 0;
	for (; i < index; i++)
		tmp.m_str[i] = this->m_str[i];
	for (int j = 0; j < letter.m_length; j++)
		tmp.m_str[i + j] = letter[j];
	i = i + letter.m_length;
	for (; i < tmp.m_length; i++)
		tmp.m_str[i] = this->m_str[i - letter.m_length];
	tmp.m_str[i] = '\0';
	return tmp;
}

//字符串翻转
String String::reverse()
{
	String tmp;
	if (this->m_length == 0) return tmp;
	tmp.m_length = this->m_length;
	tmp.m_str = new char[tmp.m_length + 1];
	int i = 0;
	for (; this->m_str[i] != '\0'; i++)
	{
		tmp.m_str[tmp.m_length - i - 1] = this->m_str[i];
	}
	tmp.m_str[i] = '\0';
	return tmp;
}

//重载关系运算符>
bool String::operator>(const String& another)
{
	if (strcmp(this->m_str, another.m_str) > 0)
		return true;
	else
		return false;
}

//重载关系运算符<
bool String::operator<(const String& another)
{
	if (strcmp(this->m_str, another.m_str) < 0)
		return true;
	else
		return false;
}

//重载“<<”
ostream& operator<<(ostream& out, const String& another)
{
	out << another.m_str;
	return out;
}

//重载“>>”
istream& operator>>(istream& in,  String& another)
{
	in >> another.m_str;
	another.m_length = strlen(another.m_str);
	if (!in)
		another = String();
	return in;
}

//重载关系运算符==
bool String::operator==(const String&another)
{
	if (strcmp(this->m_str, another.m_str) ==  0)
		return true;
	else
		return false;
}

//重载关系运算符[]
char& String::operator[](int idx)
{
	return m_str[idx];
}

//字符串初始化(地址不变)
void String::clear()
{
	this->m_length = 0;
	this->m_str[0] = '\0';
}

//字符串小写转大写
void String::toUpperCase()
{
	for (int i = 0; m_str[i] != '\0'; i++) 
		if (m_str[i] >= 'a' && m_str[i] <= 'z')
			m_str[i] -= 32;
}

//字符串大写转小写
void String::toLowerCase()
{
	for (int i = 0; m_str[i] != '\0'; i++)
		if (m_str[i] >= 'A' && m_str[i] <= 'Z')
			m_str[i] += 32;
}

//字符串交换内容
void String::exchange(String& another)
{
	String tmp;  //用来临时复制this
	tmp.m_length = this->m_length;
	delete[]tmp.m_str;
	tmp.m_str = new char[tmp.m_length + 1];
	strcpy_s(tmp.m_str, m_length + 1, this->m_str);
	String tmp_another;  //用来临时复制another
	tmp_another.m_length = another.m_length;
	delete[]tmp_another.m_str;
	tmp_another.m_str = new char[tmp_another.m_length + 1];
	strcpy_s(tmp_another.m_str, tmp_another.m_length + 1, another.m_str);
	*this = tmp_another;  //交换
	another = tmp;
	tmp.~String();
	tmp_another.~String();
}

//查找字符串
int String::find(String s)
{
	for (int i=0;i<=this->m_length-s.m_length;i++)
	{
		int j = 0, k = i;
		for (;j<s.m_length;)
			if (this->m_str[k++] != s.m_str[j++])
				break;
		if (j == s.m_length)
			return i;
	}
	return -1;
}

查找字符串
int String::find(char* s)
{
	for (int i = 0; i <= this->m_length - strlen(s); i++)
	{
		int j = 0, k = i;
		for (; j < strlen(s);)
			if (this->m_str[k++] != s[j++])
				break;
		if (j == strlen(s))
			return i;
	}
	return -1;
}

//屏幕输出字符串
void String::display()
{
	for (size_t i = 0; i < m_length; i++)
		cout << m_str[i];
	cout << endl;
}

//从文件读取字符串
String String::read(char* filename)
{
	String tmp;
	tmp.m_length = 1024;
	tmp.m_str = new char[tmp.m_length + 1];
	std::ifstream ifile(filename);
	//将文件读入到ostringstream对象buf中
	ifile.getline(tmp.m_str, tmp.m_length); //读取一行
	ifile.close();
	return tmp;
}

//将字符串复制写入文件
void String::writeCopy()
{
	char ch[] = "复制:";
	this->write(ch, *this);
	cout << "字符串复制,写入文件""String.txt""成功:" << this->m_str << endl;
}

//字符串连接后写入文件
void String::writeConnect(const String& another)
{
	char ch[] = "字符串连接:";
	String tmp;
	tmp = *this + another;
	this->write(ch, tmp);
	cout << "字符串连接,写入文件""String.txt""成功:" << tmp.m_str << endl;
}

//将限定范围内子串写入文件
void String::writeSubstr(int start, int end)
{
	char ch[] = "子串:";
	String tmp;
	tmp = this->substr(start, end);
	this->write(ch, tmp);
	cout << "子串连接,写入文件""String.txt""成功:" << tmp.m_str << endl;
}

//消除字符串中的空格并写入文件
void String::writeRemoveSpaces()
{
	char ch[] = "消除空格后:";
	String tmp;
	tmp = this->removeSpaces();
	this->write(ch, tmp);
	cout << "字符串消除空格,写入文件""String.txt""成功:" << tmp.m_str << endl;
}

//消除字符串中指定字符并写入文件
void String::writeRemoveChar(const char& ch1)
{
	char ch[] = "消除后:";
	String tmp;
	tmp = this->removeChar(ch1);
	this->write(ch, tmp);
	cout << "字符串消除指定字符,写入文件""String.txt""成功:" << tmp.m_str << endl;
}

//字符串指定位置添加字符并写入文件
void String::writeInsert(int index, char letter)
{
	char ch[] = "添加后:";
	String tmp;
	tmp = this->insert(index, letter);
	this->write(ch, tmp);
	cout << "字符串添加指定字符,写入文件""String.txt""成功:" << tmp.m_str << endl;
}

//字符串指定位置添加字符串并写入文件
void String::writeInsert(int index, char* letter)
{
	char ch[] = "添加后:";
	String tmp;
	tmp = this->insert(index, letter);
	this->write(ch, tmp);
	cout << "字符串添加指定字符串,写入文件""String.txt""成功:" << tmp.m_str << endl;
}

//字符串指定位置添加字符串并写入文件
void String::writeInsert(int index, String letter)
{
	char ch[] = "添加后:";
	String tmp;
	tmp = this->insert(index, letter);
	this->write(ch, tmp);
	cout << "字符串添加指定字符串,写入文件""String.txt""成功:" << tmp.m_str << endl;
}

//字符串翻转并写入文件
void String::writeReverse()
{
	char ch[] = "翻转后:";
	String tmp;
	tmp = this->reverse();
	this->write(ch, tmp);
	cout << "字符串翻转,写入文件""String.txt""成功:" << tmp.m_str << endl;
}

//文件清空
void String::writeClear()
{
	char ch[1] = { 0 };
	String tmp;
	this->write(ch, tmp);
	cout << "清空文件""String.txt""成功:" <<  endl;
}

//字符串小写转大写并写入文件
void String::writeToUpperCase()
{
	char ch[] = "转大写后:";
	this->toUpperCase();
	this->write(ch, *this);
	cout << "字符串转大写,写入文件""String.txt""成功:" << this->m_str << endl;
}

//字符串大写转小写并写入文件
void String::writeToLowerCase()
{
	char ch[] = "转小写后:";
	this->toLowerCase();
	this->write(ch, *this);
	cout << "字符串转小写,写入文件""String.txt""成功:" << this->m_str << endl;
}


测试文件:demo.cpp

#include "_string.h"

int main()
{
    String a("hEllllo Hello heLLo");
    String b("world");
    String c(a);
    String d;
    char f[]="hay";
    /*c.display();
    cout << "c[1]:" << c[1] << endl;
    c = b;
    c.display();
    d = a + c;
    d.display();

    if (a > b) cout << "a>b";
    else   cout << "a<=b";

    a.display();
    a.toLowerrCase();
    a.display();

    d = a.Substr(0, 6);
    d.display();

    a.exchange(b);
    a.display();
    b.display();

    d = a.Remove_Spaces();
    d.display();

	d = a.Remove_Char('o');
	d.display();

    d = a.reverse();
    d.display();

    int x = a.Find(f);
    cout << x << endl;

    d = a.set(1, f);
    d.display();

    char filename[] = "String.txt";
    d = d.read(filename);
    d.display();

    a.writeToLowerCase();

    cin >> a;
    cout << a << endl;*/
 

    system("pause");
}


  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LiuZuqiang_3027

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

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

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

打赏作者

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

抵扣说明:

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

余额充值