一、学到的知识
- 函数的
具体实现
- 复习了
文档注释
@author 注明作者
@date 注明时间
@brief 注明类,函数,变量的作用
@param 注明函数的参数作用
@return 注明函数的返回值作用 - 使用常量代替写死的数值,(结束符是否有必要使用常量,存疑)
constexpr
关键字的使用 - 函数参数输入前请判断一下
是否合法
,在字符串操作中主要注意的是:不能为空字符串,字符串长度不合要求 - 假如 String 是一个字符串,那么使用*取值的
优先级
,要比使用后置++自增的优先级高,这样可以写出*String++
的代码,但是注意在循环条件中谨慎使用,*String++ 也意味着无论条件是否成立,String都会++ - 注意字符串结束符 ‘\0’ 的使用,它意味这字符串的结束,不添加会导致乱码或者字符串读取错误。
二、代码
非完整项目代码
CString.h
/**
* @brief 学习C++
* @author Moota
* @date 2023-02-20
*/
#pragma once
#include "../../../Core/Base/Object.h"
#include "../../Utils/Exception/Exception.h"
/**
* @brief C语言中的常用字符串操作类
*/
class FCString : public UObject
{
private:
// 结束符
static constexpr char EndMark = '\0';
public:
/**
* @brief 计算给定字符串的长度,不包含'\0'
* @param Content 待计算的字符串
* @return 字符串的长度
*/
static int Strlen(const char* Content);
/**
* @brief 字符串复制函数,把含有'\0'结束符的字符串复制到另一个字符串
* 另一个字符串需要有足够的空间,否则会报错
* @param BaseString 目标字符串
* @param ExtraString 待复制字符串
*/
static void Strcpy(char* BaseString, const char* ExtraString);
/**
* @brief 用于判断指定字符串是某字符串的子串
* 如果是,返回首次出现的地址
* 如果不是,返回-1
* @param BaseString 目标字符串
* @param SubString 待查找子串
* @return 子串首次出现的索引
*/
static int Strstr(const char* BaseString, const char* SubString);
/**
* @brief 把某字符串连接到目标字符串的后面,要保证目标字符串足够长
* @param BaseString 目标字符串
* @param ExtraString 连接字符串
*/
static void Strcat(char* BaseString, const char* ExtraString);
/**
*@breif 按ASCII码比较两个字符串
* 大于返回1
* 等于返回0
* 小于返回-1
* @param StringA 第一个字符串
* @param StringB 第二个字符串
* @return 比较结果
*/
static int Strcmp(const char* StringA, const char* StringB);
};
CString.cpp
#include "CString.h"
int FCString::Strlen(const char* Content)
{
if (Content == nullptr)
{
throw FException("无法计算为空的字符串长度");
}
int Length = 0;
while (*Content != EndMark)
{
++Content;
++Length;
}
return Length;
}
void FCString::Strcpy(char* BaseString, const char* ExtraString)
{
if (BaseString == nullptr || ExtraString == nullptr)
{
throw FException("请使用不为空的字符串进行操作");
}
if (Strlen(BaseString) < Strlen(ExtraString))
{
throw FException("请确保目标字符串有足够的空间");
}
char* Temp = BaseString;
while (*ExtraString != EndMark)
{
*Temp++ = *ExtraString++;
}
*Temp = EndMark;
}
int FCString::Strstr(const char* BaseString, const char* SubString)
{
if (BaseString == nullptr || SubString == nullptr)
{
return -1;
}
const int BaseSize = Strlen(BaseString);
const int SubSize = Strlen(SubString);
if (BaseSize < SubSize)
{
return -1;
}
const int EndSize = BaseSize - SubSize;
for (int i = 0; i <= EndSize; ++i)
{
int j;
for (j = 0; j < SubSize; ++j)
{
if (BaseString[i + j] != SubString[j])
{
break;
}
}
if (j == SubSize)
{
return i;
}
}
return -1;
}
void FCString::Strcat(char* BaseString, const char* ExtraString)
{
if (BaseString == nullptr || ExtraString == nullptr)
{
throw FException("请使用不为空的字符串进行操作");
}
char* Temp = BaseString;
while (*Temp != EndMark)
{
Temp++;
}
while (*ExtraString != EndMark)
{
*Temp++ = *ExtraString++;
}
*Temp = EndMark;
}
int FCString::Strcmp(const char* StringA, const char* StringB)
{
if (StringA == nullptr || StringB == nullptr)
{
throw FException("请使用不为空的字符串进行操作");
}
int Result = 0;
while ((Result = (*StringA - *StringB)) == 0 && *StringA != EndMark)
{
++StringA;
++StringB;
}
if (Result > 0)
{
return 1;
}
else if (Result < 0)
{
return -1;
}
else
{
return 0;
}
}