【SEU程序设计课笔记】 19 - 2020/12/17 - Write C++ programs - 类/封装/tvj::string类

写一个 string类,目标:输出 Hello World。

程序

String.h

#pragma once
#define _TVJ_STRING_

#include <Windows.h>
#include <iostream>

namespace tvj
{

	template<typename ValueType>
	class Heap_Vector
	{
	public:
		Heap_Vector(int n);
		Heap_Vector();
		~Heap_Vector();
		// similar to the function of push_back in vector
		void push_back(const ValueType& value);
		void pop_back();
		ValueType& operator [](const int& index);
		ValueType operator [](const int& index) const;
		const int size() const;
		ValueType* into_array();
	private:
		ValueType* vec;
		int capacity;
		int content_number;
		void expand();
	};

	class string
	{
		friend std::istream& operator>>(std::istream& in, tvj::string& str);
		friend std::ostream& operator<<(std::ostream& in, const tvj::string& str);
		friend tvj::string toupper(tvj::string s);
		friend tvj::string tolower(tvj::string s);
	public:
		string(const char* init_string);
		string(const char& init_char);
		string(const int& n, const char& init_char);
		string(const string& init_string);
		//string(const int& init_int);
		//string(const double& init_double);
		//string clear();
		int size() const;
		int length() const;
		//string left(int n);
		//string right(int n);
		//string substr(int n1, int n2);
		string append(const string& str);
		string operator+(const string& str);
		string operator+(const char* str);
		string operator+(const char& str);
		void operator+=(const string& str);
		char& operator[](const int& n);
		char operator[](const int& n) const;
		string& operator=(const string& init_string);

	private:
		int Length = 0;
		Heap_Vector<char> char_vector;
	};

	std::istream& operator>>(std::istream& in, string& str);
	std::ostream& operator<<(std::ostream& in, const string& str);

	char toupper(char);
	string toupper(string&);
	char tolower(char);
	string tolower(string&);
	//string strcat(string&, const string&);
	//string strcpy(string&, const string&);
	//std::istream& getline(std::istream&, const string&);
}

String.cpp

#include "String.h"

tvj::string::string(const char* init_string) : Length(0)
{
	if (init_string != nullptr)
	{
		for (int i = 0; init_string[i] != '\0'; i++)
		{
			char_vector.push_back(init_string[i]);
		}
		Length = char_vector.size();
		char_vector.push_back('\0');
	}
}

tvj::string::string(const char& init_char) : Length(1)
{
	if (init_char == EOF)
	{
		Length = 0;
	}
	else if (init_char == '\0')
	{
		this->char_vector.push_back('\0');
		Length = 0;
	}
	else
	{
		this->char_vector.push_back(init_char);
		this->char_vector.push_back('\0');
		Length = 1;
	}
}

tvj::string::string(const int& n, const char& init_char)
{
	if (init_char == EOF)
	{
		this->Length = 0;
	}
	else
	{
		if (n < 0)
		{
			MessageBox(NULL, L"Number can not be negative", L"Error", MB_ICONERROR);
		}
		else
		{
			for (int i = 0; i != n; i++)
			{
				this->char_vector.push_back(init_char);
				this->Length = n;
			}
			if (init_char != '\0')
			{
				this->char_vector.push_back(init_char);
			}
			this->Length = char_vector.size();
			this->char_vector.push_back('\0');
		}
	}
}

tvj::string::string(const string& init_string)
{
	for (int i = 0; i != init_string.length() && init_string[i] != '\0'; i++)
	{
		this->char_vector.push_back(init_string[i]);
		
	}
	this->Length = init_string.length();
	this->char_vector.push_back('\0');
}

int tvj::string::size() const
{
	return (this->char_vector.size() == 0) ? 0 : (1 + this->Length);
}

int tvj::string::length() const
{
	return this->Length;
}

//tvj::string::string(const int& init_int)
//{
//	
//}
//
//tvj::string::string(const double& init_double)
//{
//
//}

//tvj::string tvj::string::clear()
//{
//	
//}

//tvj::string tvj::string::left(int n)
//{
//
//}
//
//tvj::string tvj::string::right(int n)
//{
//
//}
//
//tvj::string tvj::string::substr(int n1, int n2)
//{
//
//}

tvj::string tvj::string::append(const string& str)
{
	if (this->char_vector.size() != 0)
	{
		this->char_vector.pop_back();
		for (int i = 0; i != str.length() && str[i] != '\0'; i++)
		{
			this->char_vector.push_back(str[i]);
			this->Length++;
		}
		this->char_vector.push_back('\0');
	}
	else
	{
		*this = str;
	}
	return *this;
}

tvj::string tvj::string::operator+(const string& str)
{
	return this->append(str);
}

tvj::string tvj::string::operator+(const char* str)
{
	string init(str);
	return this->append(init);
}

tvj::string tvj::string::operator+(const char& str)
{
	string init(str);
	return this->append(init);
}

void tvj::string::operator+=(const string& str)
{
	*this = *this + str;
}

char& tvj::string::operator[](const int& n)
{
	return this->char_vector[n];
}

char tvj::string::operator[](const int& n) const
{
	return this->char_vector[n];
}

tvj::string& tvj::string::operator=(const string& init_string)
{
	string temp_str(init_string);
	return temp_str;
}

std::istream& tvj::operator>>(std::istream& in, tvj::string& str)
{
	tvj::Heap_Vector<char> temp_vector;
	char temp_ch;
	while (in >> temp_ch && (temp_ch != EOF && temp_ch != ' ' && temp_ch != '\t' && temp_ch != '\r' && temp_ch != '\n'))
	{
		temp_vector.push_back(temp_ch);
	}
	str = temp_vector.into_array();
	return in;
}

std::ostream& tvj::operator<<(std::ostream& out, const tvj::string& str)
{
	for (int i = 0; i != str.size(); i++)
	{
		out << str.char_vector[i];
	}
	return out;
}

char tvj::toupper(char c)
{
	if ('a' < c && c < 'z')
	{
		c += 'A' - 'a';
	}
	return c;
}

tvj::string tvj::toupper(tvj::string s)
{
	for (int i = 0; i != s.size(); i++)
	{
		s.char_vector[i] = toupper(s.char_vector[i]);
	}
	return s;
}

char tvj::tolower(char c)
{
	if ('A' < c && c < 'Z')
	{
		c -= 'A' - 'a';
	}
	return c;
}

tvj::string tvj::tolower(tvj::string s)
{
	for (int i = 0; i != s.length(); i++)
	{
		(s.char_vector)[i] = tolower(s.char_vector[i]);
	}
	return s;
}

//tvj::string strcat(tvj::string&, const tvj::string&)
//{
//
//}
//
//tvj::string strcpy(tvj::string&, const tvj::string&)
//{
//
//}
//
//std::istream& getline(std::istream&, const tvj::string&)
//{
//
//}

template<typename ValueType>
tvj::Heap_Vector<ValueType>::Heap_Vector(int n) :capacity(n), content_number(0), vec(new ValueType[n]) {}

template<typename ValueType>
tvj::Heap_Vector<ValueType>::Heap_Vector() : capacity(8), content_number(0), vec(new ValueType[8]) {}

template<typename ValueType>
tvj::Heap_Vector<ValueType>::~Heap_Vector() // destructor
{
	delete[] vec; // free the dynamic array
}

// similar to the function of push_back in vector
template<typename ValueType>
void tvj::Heap_Vector<ValueType>::push_back(const ValueType& value)
{
	if (content_number == capacity)
	{
		expand();
	}
	vec[content_number++] = value;
}

template<typename ValueType>
void tvj::Heap_Vector<ValueType>::pop_back()
{
	content_number--;
}

template<typename ValueType>
ValueType& tvj::Heap_Vector<ValueType>::operator[](const int& index)
{
	if (index >= this->size())
	{
		MessageBox(NULL, L"Subscript out of range.", L"Runtime Error", MB_ICONERROR);
		return vec[0];
	}
	else
	{
		return vec[index];
	}
}

template<typename ValueType>
ValueType tvj::Heap_Vector<ValueType>::operator[](const int& index) const
{
	if (index >= this->size())
	{
		MessageBox(NULL, L"Subscript out of range.", L"Runtime Error", MB_ICONERROR);
		return vec[0];
	}
	else
	{
		return vec[index];
	}
}

template<typename ValueType>
const int tvj::Heap_Vector<ValueType>::size() const
{
	return content_number;
}

template<typename ValueType>
ValueType* tvj::Heap_Vector<ValueType>::into_array()
{
	return this->vec;
}

template<typename ValueType>
void tvj::Heap_Vector<ValueType>::expand()
{
	// 1. ask for new space for the array
	ValueType* new_vec = new ValueType[2 * capacity];
	// 2. copy the values over
	for (int i = 0; i != content_number; i++)
		new_vec[i] = vec[i];
	// 3. delete the old array
	delete[] vec;
	// 4. point vec to new array
	vec = new_vec;
	// 5. update capacity (twice the capacity)
	capacity *= 2;
}

Main.cpp

#include <iostream>
#include "String.h"
using std::cin;
using std::cout;
using std::endl;
using tvj::string;

int main(int argc, char** argv)
{
	string str1("He");
	str1 += "llo";
	string str2 = " ";
	str2.append("Warl");
	string str = str1 + str2;
	str += 'd';
	str[7] = 'o';
	cout << str << endl;
	return 0;
}

输出示例

Output

分析


ALL RIGHTS RESERVED © 2020 Teddy van Jerry
欢迎转载,转载请注明出处。


See also

Teddy van Jerry 的导航页

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值