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");
}