char 배열을 이용한 string class 구현

// MyString.h ////////////////////////////////////////////////////
#pragma once
namespace assignment1
{
	class MyString
	{
	public:
		MyString(const char* s);
		MyString(const MyString& other);
		~MyString();

		unsigned int GetLength() const;
		const char* GetCString() const;
		void Append(const char* s);
		MyString operator+(const MyString& other) const;
		int IndexOf(const char* s);
		int LastIndexOf(const char* s);
		void Interleave(const char* s);
		bool RemoveAt(unsigned int i);
		void PadLeft(unsigned int totalLength);
		void PadLeft(unsigned int totalLength, const char c);
		void PadRight(unsigned int totalLength);
		void PadRight(unsigned int totalLength, const char c);
		void Reverse();
		bool operator==(const MyString& rhs) const;
		MyString& operator=(const MyString& rhs);
		void ToLower();
		void ToUpper();
	private:
		const int PAD_LEFT = 0;
		const int PAD_RIGHT = 1;
		char* mString;
		int mStringLength;

		void pad(unsigned int totalLength, const char c, int padDir);
		void swap(char& a, char& b);
		int getStrLen(const char* s) const;
		void copyMemory(char* dst, const char* src, int size) const;
		void strConcat(char* dst, const char* src) const;
	};
}
// MyString.cpp ////////////////////////////////////////////////////

#include "MyString.h"

using namespace std;

namespace assignment1
{
	MyString::MyString(const char* s)
		: mStringLength(getStrLen(s))
	{
		mString = new char[mStringLength + 1];
		copyMemory(mString, s, mStringLength + 1);
	}

	MyString::MyString(const MyString& other)
		: mStringLength(getStrLen(other.mString))
	{
		mString = new char[mStringLength + 1];
		copyMemory(mString, other.mString, mStringLength + 1);
	}

	MyString::~MyString()
	{
		delete[] mString;
	}

	unsigned int MyString::GetLength() const
	{
		return mStringLength;
	}

	const char* MyString::GetCString() const
	{
		return mString;
	}

	void MyString::Append(const char* s)
	{
		int sLen = getStrLen(s);
		if (sLen == 0)
			return;

		int length = mStringLength + sLen;
		char* strAppend = new char[length + 1];

		copyMemory(strAppend, mString, mStringLength + 1);
		delete[] mString;

		strConcat(strAppend, s);
		mString = strAppend;
		mStringLength = length;
	}

	MyString MyString::operator+(const MyString& other) const
	{
		char* result = new char[getStrLen(mString) + getStrLen(other.mString) + 1];
		copyMemory(result, mString, mStringLength + 1);
		strConcat(result, other.mString);
		MyString str = MyString(result);
		
		delete[] result;
		return str;
	}

	int MyString::IndexOf(const char* s)
	{
		int sLen = getStrLen(s);
		if (sLen == 0)
			return 0;

		int i = 0;
		int j = 0;
		int index = -1;
		int count = 0;
		for (i = 0; i < mStringLength; i++)
		{
			if (mString[i] == s[0])
			{
				count = 0;
				for (j = 0; j < sLen; j++)
				{
					if (mString[i + j] != s[j])
					{
						break;
					}
					count++;
				}

				if (count == sLen)
				{
					index = i;
					break;
				}
			}
		}

		return index;
	}

	int MyString::LastIndexOf(const char* s)
	{
		int sLen = getStrLen(s);
		if (sLen == 0)
			return mStringLength;

		int i = 0;
		int j = 0;
		int index = -1;
		int count = 0;
		for (i = mStringLength - 1; i >= 0; i--)
		{
			if (mString[i] == s[sLen - 1])
			{
				count = 0;
				int startIndex = i - (sLen - 1);
				for (j = 0; j < sLen; j++)
				{
					if (mString[startIndex + j] != s[j])
					{
						break;
					}
					count++;
				}

				if (count == sLen)
				{
					index = startIndex;
					break;
				}
			}
		}

		return index;
	}

	void MyString::Interleave(const char* s)
	{
		int sLen = getStrLen(s);
		if (sLen == 0)
			return;

		int length = mStringLength + sLen;
		char* str = new char[length + 1];

		int i = 0;
		int mIndex = 0;
		int sIndex = 0;
		for (i = 0; i < length; i++)
		{
			if (i % 2 == 0)
			{
				if (mIndex < mStringLength)
				{
					str[i] = mString[mIndex];
					mIndex++;
				}
				else
				{
					str[i] = s[sIndex];
					sIndex++;
				}
			}
			else if (i % 2 == 1)
			{
				if (sIndex < sLen)
				{
					str[i] = s[sIndex];
					sIndex++;
				}
				else
				{
					str[i] = mString[mIndex];
					mIndex++;
				}
			}
		}

		str[length] = 0;

		delete[] mString;

		mString = str;
		mStringLength = length;
	}

	bool MyString::RemoveAt(unsigned int index)
	{
		int idx = (signed)index;
		if (idx >= mStringLength)
			return false;

		char* str = new char[mStringLength];
		for (int i = 0; i < mStringLength; i++)
		{
			if (i < idx)
			{
				str[i] = mString[i];
			}
			else
			{
				str[i] = mString[i + 1];
			}
		}

		delete[] mString;

		mString = str;
		mStringLength = mStringLength - 1;

		return true;
	}

	void MyString::PadLeft(unsigned int totalLength)
	{
		PadLeft(totalLength, ' ');
	}

	void MyString::PadLeft(unsigned int totalLength, const char c)
	{
		pad(totalLength, c, PAD_LEFT);
	}

	void MyString::PadRight(unsigned int totalLength)
	{
		PadRight(totalLength, ' ');
	}

	void MyString::PadRight(unsigned int totalLength, const char c)
	{
		pad(totalLength, c, PAD_RIGHT);
	}

	void MyString::pad(unsigned int totalLength, const char c, int padDir)
	{
		int tLen = (signed)totalLength;
		if (tLen <= mStringLength)
			return;
		
		char* str = new char[tLen + 1];
		int addCount = tLen - mStringLength;
		int i = 0;
		for (i = 0; i < tLen; i++)
		{
			if (padDir == PAD_LEFT)
			{
				if (i < addCount)
				{
					str[i] = c;
				}
				else
				{
					str[i] = mString[i - addCount];
				}
			}
			else if (padDir == PAD_RIGHT)
			{
				if (i < mStringLength)
				{
					str[i] = mString[i];
				}
				else
				{
					str[i] = c;
				}
			}
		}
		str[tLen] = 0;

		delete[] mString;

		mString = str;
		mStringLength = tLen;
	}

	void MyString::Reverse()
	{
		int i = 0, j = mStringLength - 1;
		while (true)
		{
			if (i > j)
			{
				break;
			}
			swap(mString[i], mString[j]);
			i++;
			j--;
		}
	}

	void MyString::swap(char& a, char& b)
	{
		char temp = a;
		a = b;
		b = temp;
	}

	bool MyString::operator==(const MyString& rhs) const
	{
		if (mStringLength != rhs.mStringLength)
			return false;

		for (int i = 0; i < mStringLength; i++)
		{
			if (mString[i] != rhs.mString[i])
			{
				return false;
			}
		}
		return true;
	}

	MyString& MyString::operator=(const MyString& rhs)
	{
		if (*this == rhs)
			return *this;

		delete[] mString;

		mStringLength = rhs.mStringLength;
		mString = new char[mStringLength + 1];

		copyMemory(mString, rhs.mString, mStringLength + 1);
		return *this;
	}

	void MyString::ToLower()
	{
		for (int i = 0; i < mStringLength; i++)
		{
			if (mString[i] < 65 || mString[i] > 90)
				continue;

			mString[i] += 32;
		}
	}

	void MyString::ToUpper()
	{
		for (int i = 0; i < mStringLength; i++)
		{
			if (mString[i] < 97 || mString[i] > 122)
				continue;

			mString[i] -= 32;
		}
	}

	int MyString::getStrLen(const char* s) const
	{
		int i = 0;
		int count = 0;
		while (true)
		{
			if (s[i] == 0)
			{
				break;
			}
			count++;
			i++;
		}
		return count;
	}

	void MyString::copyMemory(char* dst, const char* src, int size) const
	{
		int i = 0;
		for (i = 0; i < size; i++)
		{
			if (i > getStrLen(src))
				break;

			dst[i] = src[i];
		}
	}

	void MyString::strConcat(char* dst, const char* src) const
	{
		int dstLen = getStrLen(dst);
		int srcLen = getStrLen(src);
		int size = dstLen + srcLen + 1;
		for (int i = dstLen; i < size; i++)
		{
			dst[i] = src[i - dstLen];
		}
	}
}

'포트폴리오' 카테고리의 다른 글

c++ binary Search Tree  (0) 2019.10.28
c++ STL container 만들기  (0) 2019.10.28
게이트식스 리뷰영상  (0) 2019.10.07
Projectile 기능  (0) 2019.10.07
에어템플릿(유니티)  (0) 2019.10.07

+ Recent posts