字符串类String

it2025-12-25  7

文章目录

1 字符串类的初步设计1.1 历史遗留问题1.2 字符串类的初步设计1.3 代码实现 2 字符串类功能的进一步实现2.1 重载数组访问操作符[]2.2 判断是否以指定字符串开始或结束2.3 在指定位置处插入字符串2.4 去掉字符串两端的空白字符

1 字符串类的初步设计

1.1 历史遗留问题

C语言不支持真正意义上的字符串。C语言用字符数组和一组函数实现字符串操作。C语言不支持自定义类型,因此无法获得字符串类型。从C到C++的进化过程中引入了自定义类型,在C++中可以通过类完成字符串类型的定义。

1.2 字符串类的初步设计

类的声明如下: 实现时的注意事项:

无缝实现String对象与char*字符串的互操作。操作符重载函数需要考虑是否支持const操作。通过C语言中的字符串函数实现String的成员函数。

1.3 代码实现

String.h:

#ifndef LSTRING_H #define LSTRING_H #include "Object.h" #include "Exception.h" namespace LemonLib { #define STR(str) (str ? str : "") class String : public Object { protected: char* m_str; int m_length; void init(const char* str); public: String(); String(const char* str); String(char c); String(const String& s); String& operator = (const char* str); String& operator = (const String& s); String& operator = (char c); bool operator == (const char* str) const; bool operator == (const String& s) const; bool operator != (const char* str) const; bool operator != (const String& s) const; bool operator > (const char* str) const; bool operator > (const String& s) const; bool operator >= (const char* str) const; bool operator >= (const String& s) const; bool operator < (const char* str) const; bool operator < (const String& s) const; bool operator <= (const char* str) const; bool operator <= (const String& s) const; String operator + (const char* str) const; String operator + (const String& s) const; String& operator += (const char* str); String& operator += (const String& s); int length() const; const char* str() const; ~String(); }; } #endif // STRING_H

String.cpp:

#include "LString.h" #include <cstring> #include <cstdlib> using namespace std; namespace LemonLib { void String::init(const char* str) { m_str = strdup(STR(str)); if (m_str != NULL) { m_length = strlen(m_str); } else { THROW_EXCEPTION(NoEnoughMemoryException, "string init error, no enough memory"); } } String::String() { init(""); } String::String(const char* str) { init(str); } String::String(char c) { char str[] = {c, '\0'}; init(str); } String::String(const String& s) { init(s.m_str); } String& String::operator = (char c) { char str[] = {c, '\0'}; return (*this = str); } String& String::operator = (const char* str) { if (m_str != str) { free(m_str); init(str); } return *this; } String& String::operator = (const String& s) { return (*this = s.m_str); } int String::length() const { return m_length; } const char* String::str() const { return m_str; } bool String::operator == (const char* str) const { return strcmp(m_str, str) == 0; } bool String::operator == (const String& s) const { return (*this == s.m_str); } bool String::operator != (const char* str) const { return !(*this == str); } bool String::operator != (const String& s) const { return !(*this == s); } bool String::operator > (const char* str) const { return strcmp(m_str, STR(str)) > 0; } bool String::operator > (const String& s) const { return (*this > s.m_str); } bool String::operator >= (const char* str) const { return strcmp(m_str, STR(str)) >= 0; } bool String::operator >= (const String& s) const { return (*this >= s.m_str); } bool String::operator < (const char* str) const { return strcmp(m_str, str) < 0; } bool String::operator < (const String& s) const { return (*this < s.m_str); } bool String::operator <= (const char* str) const { return strcmp(m_str, STR(str)) <= 0; } bool String::operator <= (const String& s) const { return (*this <= s.m_str); } String String::operator + (const char* str) const { int len = m_length + strlen(STR(str)); String ret; char* p = reinterpret_cast<char*>(malloc(len + 1)); if (p != NULL) { strcpy(p, m_str); strcat(p, STR(str)); free(ret.m_str); ret.m_str = p; ret.m_length = len; return ret; } else { THROW_EXCEPTION(NoEnoughMemoryException, "string operator + error, no enough memory"); } } String String::operator + (const String& s) const { return (*this + s.m_str); } String& String::operator += (const char* str) { return (*this = *this + str); } String& String::operator += (const String& s) { return (*this += s.m_str); } String::~String() { free(m_str); } }

2 字符串类功能的进一步实现

接下来主要实现如下函数:

2.1 重载数组访问操作符[]

函数声明:

char& operator [] (int i); char operator [] (int i) const;

注意事项:

当i的取值不合法时,抛出异常: 合法范围:(0 <= i) && (i < m_length)

代码实现如下:

char& String::operator [] (int i) { if ((0 <= i) && (i < m_length)) { return m_str[i]; } else { THROW_EXCEPTION(IndexOutOfBoundsException, "string operator [] error, out index"); } } char String::operator [] (int i) const { return (const_cast<String&>(*this))[i]; }

2.2 判断是否以指定字符串开始或结束

函数声明:

bool startWith(const char* s) const; bool startWith(const String& s) const; bool endOf(const char* s) const; bool endOf(const String& s) const;

示意图: 代码实现:

bool String::is_equal(const char* str1, const char* str2, int len) const { bool ret = true; for (int i=0; i<len; i++) { if (str1[i] != str2[i]) { ret = false; break; } } return ret; } bool String::startWith(const char* s) const { bool ret = (s != NULL); if (ret) { int len = strlen(s); ret = (len < m_length) && is_equal(m_str, s, len); } return ret; } bool String::startWith(const String& s) const { return startWith(s.m_str); } bool String::endOf(const char* s) const { bool ret = (s != NULL); if (ret) { int len = strlen(s); ret = (len < m_length) && is_equal(m_str + m_length - len, s, len); } return ret; } bool String::endOf(const String& s) const { return endOf(s.m_str); }

2.3 在指定位置处插入字符串

函数声明:

String& insert(int i, const char* s); String& insert(int i, const String& s);

示意图:

代码实现:

String& String::insert(int i, const char* s) { bool ret = (s != NULL); if (ret) { if ((0 <= i) && (i <= m_length)) { int len = strlen(s); char* str = reinterpret_cast<char*>(malloc(m_length + len + 1)); if (str != NULL) { strncpy(str, m_str, i); strncpy(str+i, s, len); strncpy(str+i+len, m_str+i, m_length-i); str[m_length+len] = '\0'; free(m_str); m_str = str; m_length = m_length + len + 1; } else { THROW_EXCEPTION(NoEnoughMemoryException, "string insert error, no enough memory"); } } } return *this; } String& String::insert(int i, const String& s) { return insert(i, s.m_str); }

2.4 去掉字符串两端的空白字符

函数声明:

String& trim();

示意图: 代码实现:

String& String::trim() { if (m_length > 0) { int begin = 0, end = m_length - 1; while (m_str[begin] == ' ') begin++; while (m_str[end] == ' ') end--; if (begin == 0) { m_str[end + 1] = '\0'; m_length = end + 1; } else { for (int i=0, j=begin; j<=end; i++, j++) { m_str[i] = m_str[j]; } m_str[end - begin + 1] = '\0'; m_length = end - begin + 1; } } return *this; }
最新回复(0)