【数据结构】40_字符串类的创建 (下)

入画
• 阅读 1048

字符串类的常用函数

成员函数 功能描述
operator[](i) 操作符重载函数,访问指定下标的字符
startWith(s) 判断字符串是否以 s 开头
endOf(s) 判断字符串是否以 s 结尾
insert(i,s) 在字符串的位置 i 插入 s
trim() 去掉字符串两端的空白

重载数组访问操作符[]

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

    • 注意事项

      • 当 i 的取值不合法时,抛出异常

        • 合法范围: (0 <= i) && (i < m_length)

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

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

【数据结构】40_字符串类的创建 (下)

【数据结构】40_字符串类的创建 (下)

在指定位置插入字符串

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

【数据结构】40_字符串类的创建 (下)

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

  • String &trim();

【数据结构】40_字符串类的创建 (下)

编程实验:常用成员函数的实现

文件:DTString.h

#ifndef STRING_H
#define STRING_H

#include "Exception.h"
#include "Object.h"

#include <cstdint>

namespace DTLib
{

class String
{
public:
    String();
    String(const String &s);
    String(const char* s);

    size_t length() const;
    const char *str() const;

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

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

    String &trim();

    bool operator == (const char *s) const;
    bool operator == (const String &s) const;
    bool operator != (const char *s) const;
    bool operator != (const String &s) const;
    bool operator > (const char *s) const;
    bool operator > (const String &s) const;
    bool operator < (const char *s) const;
    bool operator < (const String &s) const;
    bool operator >= (const char *s) const;
    bool operator >= (const String &s) const;
    bool operator <= (const char *s) const;
    bool operator <= (const String &s) const;

    String operator + (const char *s) const;
    String operator + (const String &s) const;
    String &operator += (const char *s);
    String &operator += (const String &s);

    String &operator = (const char c);
    String &operator = (const char *s);
    String &operator = (const String &s);

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

    ~String();

protected:
    char *m_str = nullptr;
    size_t m_length = 0;
};

}

#endif // STRING_H

文件:DTString.cpp

#include "DTString.h"

#include <cstring>
#include <cstdlib>

namespace DTLib
{

String::String() : String("")
{
}

String::String(const String &s) : String(s.m_str)
{
}

String::String(const char* s)
{
    char* str = strdup(s);

    if (str != nullptr)
    {
        m_str = str;

        m_length = strlen(str);
    }
    else
    {
        THROW_EXCEPTION(NoEnoughMemoryException, "No enogh memory to create str object ...");
    }
}

size_t String::length() const
{
    return m_length;
}

const char *String::str() const
{
    return m_str;
}

bool String::startWith(const char *s) const
{
    bool ret = (s != nullptr);

    if (ret)
    {
        size_t len = strlen(s);

        ret = (m_length > len) && (strncmp(m_str, s, len) == 0);
    }

    return ret;
}

bool String::startWith(const String &s) const
{
    return startWith(s.str());
}

bool String::endOf(const char *s) const
{
    bool ret = (s != nullptr);

    if (ret)
    {
        size_t len = strlen(s);
        char *str = m_str + (m_length - len);

        ret = (m_length > len) && (strncmp(str, s, len) == 0);
    }

    return ret;
}

bool String::endOf(const String &s) const
{
    return endOf(s.str());
}

String &String::insert(size_t i, const char *s)
{
    if (i <= m_length)
    {
        if ((s != nullptr) || s[0] != '\0')
        {
            size_t len = strlen(s);
            char *str = reinterpret_cast<char*>(malloc(m_length + len + 1));

            if (str != nullptr)
            {
               strncpy(str, m_str, i);
               strncpy(str + i, s, len);
               strncpy(str + i + len, m_str + i, m_length - i);
               str[len + m_length] = '\0';

                free(m_str);
                m_str = str;
                m_length = m_length + len;
            }
            else
            {
                THROW_EXCEPTION(NoEnoughMemoryException, "No memory to insert str object ...");
            }
        }
    }
    else
    {
        THROW_EXCEPTION(IndexOutOfBoundsException, "Parameter i is invalid");
    }

    return *this;
}

String &String::insert(size_t i, const String &s)
{
    return insert(i, s.str());
}

String &String::trim()
{
    size_t b = 0;
    size_t e = m_length - 1;

    while (m_str[b] == ' ') b++;
    while (m_str[e] == ' ') e--;

    if (b == 0)
    {
        m_str[e + 1] = '\0';
        m_length = e + 1;
    }
    else
    {
        for (size_t i=0, j = b; j<=e; ++i, ++j)
        {
            m_str[i] = m_str[j];
        }

        m_str[e - b + 1] = '\0';
        m_length = e - b + 1;
    }

    return *this;
}

bool String::operator == (const char *s) const
{
    return (strcmp(m_str, s ? s : "") == 0);
}

bool String::operator == (const String &s) const
{
    return (strcmp(m_str, s.str()) == 0);
}

bool String::operator != (const char *s) const
{
    return (strcmp(m_str, s ? s : "") != 0);
}

bool String::operator != (const String &s) const
{
    return (strcmp(m_str, s.str()) != 0);
}

bool String::operator > (const char *s) const
{
    return (strcmp(m_str, s ? s : "") > 0);
}

bool String::operator > (const String &s) const
{
    return (strcmp(m_str, s.str()) > 0);
}

bool String::operator < (const char *s) const
{
    return (strcmp(m_str, s ? s : "") < 0);
}

bool String::operator < (const String &s) const
{
    return (strcmp(m_str, s.str()) < 0);
}

bool String::operator >= (const char *s) const
{
    return (strcmp(m_str, s ? s : "") >= 0);
}

bool String::operator >= (const String &s) const
{
    return (strcmp(m_str, s.str()) >= 0);
}

bool String::operator <= (const char *s) const
{
    return (strcmp(m_str, s ? s : "") <= 0);
}

bool String::operator <= (const String &s) const
{
    return (strcmp(m_str, s.str()) <= 0);
}

String String::operator + (const char *s) const
{
    String ret;

    size_t len = m_length + strlen(s ? s : "");

    char *str = reinterpret_cast<char*>(malloc(len + 1));

    if (str != nullptr)
    {
        strcpy(str, m_str);
        strcat(str, s ? s : "");

        free(ret.m_str);

        ret.m_str = str;
        ret.m_length = len;
    }
    else
    {
        THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create str object ...");
    }

    return ret;
}

String String::operator + (const String &s) const
{
    return (*this + s.str());
}

String &String::operator += (const char *s)
{
    return (*this = *this + s);
}

String &String::operator += (const String &s)
{
    return (*this = *this + s.str());
}

String &String::operator = (const char c)
{
    char s[] = {c, '\0'};

    return (*this = s);
}

String &String::operator = (const char *s)
{
    if (m_str != s)
    {
        char *str = strdup(s ? s : "");

        if (str != nullptr)
        {
            free(m_str);

            m_str = str;
            m_length = strlen(str);
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create str object ...");
        }
    }

    return *this;
}

String &String::operator = (const String &s)
{
    return (*this = s.str());
}

char &String::operator[] (size_t i)
{
    if (i < m_length)
    {
        return m_str[i];
    }
    else
    {
        THROW_EXCEPTION(InvalidParameterExcetion, "Parameter i invalid...");
    }
}

char String::operator[] (size_t i) const
{
    return const_cast<String&>(*this)[i];
}

String::~String()
{
    free(m_str);
}

}

文件:main.cpp

输出

#include <iostream>
#include "DTString.h"

using namespace std;
using namespace DTLib;

int main()
{
    String s = "D.T.Software";

    cout << s.startWith("D.T.") << endl;
    cout << s.endOf("Software") << endl;

    for (size_t i=0; i<s.length(); ++i)
    {
        cout << s[i] << " ";
    }

    cout << "----" << endl;

    String s1 = "";
    s1.insert(0, "D.T.");
    s1.insert(4, "Software");

    cout << s1.str() << endl;

    cout << "----" << endl;

    String s2 = "  abc  ";

    if (s2.trim().insert(0, "D.T.").endOf("abc") && s2.startWith("D.T."))
    {
        cout << s2.str() << endl;
    }

    return 0;
}

输出:

1
1
D . T . S o f t w a r e ----
D.T.Software
----
D.T.abc

To be continued ...

思考:如何在目标字符串中查找是否存在指定的字串
String s = "D.T.Software";
int pos = s.indexof("Software");

以上内容整理于狄泰软件学院系列课程,请大家保护原创!

点赞
收藏
评论区
推荐文章
Easter79 Easter79
4年前
top down car教程1【原创翻译老外的】
原文链接http://www.iforce2d.net/b2dtut/topdowncar最近讨论'topdown'carphysics如何很实现的话题很越来越多,所以我想我可以试一试并且展开一个话题。一个td(topdown)car被设计成在一个0重力的世界中,被一个为底盘的身体和四个分离的轮子身体。它取决于仅仅用一个带有底盘的身
Wesley13 Wesley13
4年前
java RSA算法的性能记录
环境JavaHotSpot(TM)64BitServerVM1.7.0\_05x86\_64加密<table<tr<td内容长度</td<tdkeySize</td<td耗时(微秒)</td</tr<tr<td32</td<td512</td<td87</td</tr<tr<td
红烧土豆泥 红烧土豆泥
4年前
Java的数值数据类型以及命名规范
一、Java中的数值数据类型<table<tbody<tr<tdwidth"75"valign"top"style"wordbreak:breakall;"<spanstyle"backgroundcolor:rgb(255,254,213);"类型名<br</span</td<tdwidth"299
DevOpSec DevOpSec
5年前
Linux主机安全配置
1.安全配置规范1.身份鉴别1.账号检查<tableborder"1"cellspacing"0"style"width:426.1pt;"<tbody<tr<tdstyle"width:113.4pt;"<pstyle"marginleft:0pt;"<strong<strong安全配置编号
Stella981 Stella981
4年前
Jira 使用手册
<tablestyle"width:100%;margin:200px0300px0;"<tr<thDate</th<thRevisionversion</th<thDescription</th<thauthor</th</tr<tr<td20180614</td<tdV1.0.0</td
Stella981 Stella981
4年前
Bootstrap学习笔记
1.Table:table,tablebordered,table,tablehover,tablecondensed,2.tr,td:active,success,warning,danger,info3.Form:formgroupformcontrol,forminline,formhorizontal,4.
Wesley13 Wesley13
4年前
2020软件工程作业03
<styletable{width:100%;/\表格宽度\/margin:auto;/\外边距\/emptycells:show;/\单元格无内容依旧绘制边框\/fontsize:18px;}table,th,td{border:2pxsolidpink;}li{fontsize:1
Stella981 Stella981
4年前
Django之Django模板
1、问:html页面从数据库中读出DateTimeField字段时,显示的时间格式和数据库中存放的格式不一致,比如数据库字段内容为2012082616:00:00,但是页面显示的却是Aug.26,2012,4p.m.答:为了页面和数据库中显示一致,需要在页面格式化时间,需要添加<td{{dayrecord.p\_time|date:
Wesley13 Wesley13
4年前
Java根据XPath提取HTML
有这样一段HTML: <div<table<tdid'1234foo5678'Hello</td希望通过这个XPath提取出Hello://div//tdcontains(@id,'foo')/text()先导入maven依赖:<!https://mvnrepository.com/ar
Wesley13 Wesley13
4年前
Java 日期与时间
Java的日期Java没有内置的日期类,但可以导入java.time包,这个包中包含了许多类,可用于处理日期和时间。例如:<table<tbody<tr<thstyle"width:25%"Java类</th<thstyle"width:75%"描述</th</tr<tr<td<code