分享一个安全的CString 本 CString 类是基于 C 标准库std::string封装的轻量级字符串工具类兼容常用字符串操作需求无需手动管理内存安全稳定。类提供完整的构造、赋值、拼接、比较、截取、查找、格式化等功能包含GetAt、[]运算符重载支持读写访问实现Left/Right/Mid截取、Trim去空格、大小写转换、Format格式化等实用接口。所有接口做了越界、空指针等安全校验避免程序崩溃整体简洁易用、鲁棒性强适用于日常字符串处理场景。先上测试用例#include CString.h#include cstdio// 修复后的宏定义#define TEST_CASE(str) printf(\n 测试: %s \n, str);#define CHECK(a) printf(结果: %s\n, a);int main(){//// 1. 构造函数测试//TEST_CASE(构造函数);CString s1;CString s2(hello);CString s3(A);CString s4(s2);CHECK(s1.GetBuffer(0));CHECK(s2.GetBuffer(0));CHECK(s3.GetBuffer(0));CHECK(s4.GetBuffer(0));//// 2. 基础属性//TEST_CASE(基础属性);char buf[64];sprintf(buf, 长度: %d, s2.GetLength());CHECK(buf);sprintf(buf, 是否空: %s, s1.IsEmpty() ? 是 : 否);CHECK(buf);s1.Empty();sprintf(buf, 清空后是否空: %s, s1.IsEmpty() ? 是 : 否);CHECK(buf);//// 3. 字符访问 GetAt / []//TEST_CASE(字符访问);CString s5(test123);sprintf(buf, %c, s5.GetAt(0));CHECK(buf);sprintf(buf, %c, s5[1]);CHECK(buf);s5[0] T;CHECK(s5.GetBuffer(0));//// 4. 赋值 //TEST_CASE(赋值);CString s6;s6 assign test;CHECK(s6.GetBuffer(0));s6 X;CHECK(s6.GetBuffer(0));s6 s5;CHECK(s6.GetBuffer(0));//// 5. 拼接 //TEST_CASE();CString s7(abc);s7 123;s7 4;s7 CString(567);CHECK(s7.GetBuffer(0));//// 6. 截取 Left / Right / Mid//TEST_CASE(Left / Right / Mid);CString s8(123456789);CHECK(s8.Left(3).GetBuffer(0));CHECK(s8.Right(3).GetBuffer(0));CHECK(s8.Mid(2).GetBuffer(0));CHECK(s8.Mid(2, 4).GetBuffer(0));//// 7. 查找 Find//TEST_CASE(Find);CString s9(abc123abc456);sprintf(buf, 查找字符: %d, s9.Find(c));CHECK(buf);sprintf(buf, 查找串: %d, s9.Find(123));CHECK(buf);sprintf(buf, 从位置5查找: %d, s9.Find(abc, 5));CHECK(buf);sprintf(buf, 查找CString: %d, s9.Find(CString(456)));CHECK(buf);sprintf(buf, 查找CString: %d, s9.Find(CString(xx)));CHECK(buf);//// 8. Trim 系列//TEST_CASE(Trim);CString s10( abc def \r\n);s10.TrimLeft();s10.TrimRight();sprintf(buf, TrimLeftRight: %s, s10.GetBuffer(0));CHECK(buf);CString s11( xyz );s11.Trim();sprintf(buf, Trim: %s, s11.GetBuffer(0));CHECK(buf);//// 9. 大小写 MakeLower / MakeUpper//TEST_CASE(大小写);CString s12(AbCdEfG);s12.MakeUpper();sprintf(buf, 大写: %s, s12.GetBuffer(0));CHECK(buf);s12.MakeLower();sprintf(buf, 小写: %s, s12.GetBuffer(0));CHECK(buf);//// 10. GetBuffer//TEST_CASE(GetBuffer);CString s13(buffer test);const char* pConst s13.GetBuffer(0);char* pNoConst s13.GetBuffer(0);CHECK(pConst);CHECK(pNoConst);//// 11. Format//TEST_CASE(Format);CString s14;s14.Format(编号:%d,内容:%s, 100, test string);CHECK(s14.GetBuffer(0));//// 12. 比较 ! //TEST_CASE(比较运算符);CString a(aaa), b(bbb);sprintf(buf, : %d, a b);CHECK(buf);sprintf(buf, !: %d, a ! b);CHECK(buf);sprintf(buf, : %d, a b);CHECK(buf);sprintf(buf, : %d, a b);CHECK(buf);sprintf(buf, : %d, a b);CHECK(buf);sprintf(buf, : %d, a b);CHECK(buf);sprintf(buf, const char*: %d, a aaa);CHECK(buf);//// 13. 全局 运算符//TEST_CASE( 拼接);CString x(111), y(222);CString r1 x y;CString r2 x 333;CString r3 444 y;CString r4 x 5;CHECK(r1.GetBuffer(0));CHECK(r2.GetBuffer(0));CHECK(r3.GetBuffer(0));CHECK(r4.GetBuffer(0));printf(\n 所有函数测试完成 \n);return 0;}测试结果 测试: 构造函数 结果:结果: hello结果: A结果: hello 测试: 基础属性 结果: 长度: 5结果: 是否空: 是结果: 清空后是否空: 是 测试: 字符访问 结果: t结果: e结果: Test123 测试: 赋值 结果: assign test结果: X结果: Test123 测试: 结果: abc1234567 测试: Left / Right / Mid 结果: 123结果: 789结果: 3456789结果: 3456 测试: Find 结果: 查找字符: 2结果: 查找串: 3结果: 从位置5查找: 6结果: 查找CString: 9结果: 查找CString: -1 测试: Trim 结果: TrimLeftRight: abc def结果: Trim: xyz 测试: 大小写 结果: 大写: ABCDEFG结果: 小写: abcdefg 测试: GetBuffer 结果: buffer test结果: buffer test 测试: Format 结果: 编号:100,内容:test string 测试: 比较运算符 结果: : 0结果: !: 1结果: : 0结果: : 1结果: : 0结果: : 1结果: const char*: 1 测试: 拼接 结果: 111222结果: 111333结果: 444222结果: 1115 所有函数测试完成 CString.h#ifndef CSTRING_H #define CSTRING_H #include string // 字符串封装类模拟MFC CString class CString { private: std::string m_str; // 内部存储字符串的成员变量 public: // 构造与析构 CString(); // 默认构造空字符串 CString(const CString str); // 拷贝构造 CString(const char* lpsz); // 从C字符串构造 CString(char ch); // 从单个字符构造 ~CString(); // 析构函数 // 基础属性操作 int GetLength() const; // 获取字符串长度 bool IsEmpty() const; // 判断是否为空 void Empty(); // 清空字符串 // 字符访问 char GetAt(int iIndex) const; // 获取指定位置字符带检查 char operator[](int iIndex) const; // 只读下标访问 char operator[](int iIndex); // 可写下标访问 // 赋值运算符 CString operator(const CString str); CString operator(const char* lpsz); CString operator(char ch); // 追加运算符 CString operator(const CString str); CString operator(const char* lpsz); CString operator(char ch); // 字符串截取 CString Left(int nCount) const; // 取左侧n个字符 CString Right(int nCount) const; // 取右侧n个字符 CString Mid(int nFirst) const; // 从n开始取到末尾 CString Mid(int nFirst, int nCount) const; // 从n取count个字符 // 查找函数 int Find(char ch) const; // 查找字符 int Find(const char* lpszSub) const; // 查找子串 int Find(const char* lpszSub, int nStart) const; // 从指定位置查找 int Find(const CString strSub) const; // 查找CString子串 // 修剪空白 void TrimLeft(); // 去除左侧空白 void TrimRight(); // 去除右侧空白 void Trim(); // 去除左右空白 // 大小写转换 void MakeLower(); // 转为小写 void MakeUpper(); // 转为大写 // 缓冲区操作 char* GetBuffer(int 0); // 获取可写缓冲区 const char* GetBuffer(int 0) const; // 获取只读缓冲区 void Format(const char* pstrFormat, ...); // 格式化字符串 // 比较运算符CString bool operator(const CString str) const; bool operator!(const CString str) const; bool operator(const CString str) const; bool operator(const CString str) const; bool operator(const CString str) const; bool operator(const CString str) const; // 比较运算符C字符串 bool operator(const char* lpsz) const; bool operator!(const char* lpsz) const; bool operator(const char* lpsz) const; bool operator(const char* lpsz) const; bool operator(const char* lpsz) const; bool operator(const char* lpsz) const; // 友元拼接运算符 friend CString operator(const CString s1, const CString s2); friend CString operator(const CString s1, const char* s2); friend CString operator(const char* s1, const CString s2); friend CString operator(const CString s1, char ch); }; #endifCString.cpp/* 本 CString 类是基于 C 标准库std::string封装的轻量级字符串工具类兼容常用字符串操作需求1 无需手动管理内存安全稳定。类提供完整的构造、赋值、拼接、比较、截取、查找、格式化等功能包含GetAt、 []运算符重载支持读写访问实现Left/Right/Mid截取、Trim去空格、大小写转换、Format格式化等实用接口。 所有接口做了越界、空指针等安全校验避免程序崩溃整体简洁易用、鲁棒性强适用于日常字符串处理场景。 */ #include CString.h #include cstring #include cstdarg #include cstdio #include cctype #include memory #include stdexcept // 加这个 // 默认构造空字符串 CString::CString() { } // 拷贝构造 CString::CString(const CString str) { m_str str.m_str; } // 从 C 字符串构造 CString::CString(const char* lpsz) { if(lpsz) m_str lpsz; } // 从单个字符构造 CString::CString(char ch) { m_str ch; } // 析构函数 CString::~CString() { } // 获取字符串长度 int CString::GetLength() const { return (int)m_str.size(); } // 判断是否为空 bool CString::IsEmpty() const { return m_str.empty(); } // 清空字符串 void CString::Empty() { m_str.clear(); } // 获取指定位置字符 char CString::GetAt(int iIndex) const { if(iIndex 0 || iIndex GetLength()) return 0; return m_str[iIndex]; } // 只读下标访问 char CString::operator[](int iIndex) const { return GetAt(iIndex); } // 可写下标访问 char CString::operator[](int iIndex) { if (iIndex 0 || iIndex GetLength()) { throw std::out_of_range(CString[] index out of range); } return m_str[iIndex]; } // 赋值运算符CString CString CString::operator(const CString str) { m_str str.m_str; return *this; } // 赋值运算符C字符串 CString CString::operator(const char* lpsz) { if(lpsz) m_str lpsz; else m_str.clear(); return *this; } // 赋值运算符单个字符 CString CString::operator(char ch) { m_str ch; return *this; } // 追加字符串(CString) CString CString::operator(const CString str) { m_str str.m_str; return *this; } // 追加字符串(C字符串) CString CString::operator(const char* lpsz) { if(lpsz) m_str lpsz; return *this; } // 追加单个字符 CString CString::operator(char ch) { m_str ch; return *this; } // 取左边nCount个字符 CString CString::Left(int nCount) const { if(nCount 0) return CString(); if(nCount GetLength()) nCount GetLength(); return CString(m_str.substr(0, nCount).c_str()); } // 取右边nCount个字符 CString CString::Right(int nCount) const { int len GetLength(); if(nCount 0 || len 0) return CString(); if(nCount len) nCount len; return CString(m_str.substr(len - nCount, nCount).c_str()); } // 从nFirst取到末尾 CString CString::Mid(int nFirst) const { int len GetLength(); if(nFirst 0 || nFirst len) return CString(); return CString(m_str.substr(nFirst).c_str()); } // 从nFirst取nCount个字符 CString CString::Mid(int nFirst, int nCount) const { int len GetLength(); if(nFirst 0 || nCount 0 || nFirst len) return CString(); if(nFirst nCount len) nCount len - nFirst; return CString(m_str.substr(nFirst, nCount).c_str()); } // 查找单个字符 int CString::Find(char ch) const { size_t pos m_str.find(ch); if(pos std::string::npos) return -1; return (int)pos; } // 查找子串(C字符串) int CString::Find(const char* lpszSub) const { if(!lpszSub || *lpszSub 0) return -1; size_t pos m_str.find(lpszSub); if(pos std::string::npos) return -1; return (int)pos; } // 从指定位置查找子串(C字符串) int CString::Find(const char* lpszSub, int nStart) const { if(!lpszSub) return -1; if(*lpszSub 0) return 0; if(nStart 0 || nStart GetLength()) return -1; size_t pos m_str.find(lpszSub, nStart); if(pos std::string::npos) return -1; return (int)pos; } // 查找子串(CString) int CString::Find(const CString strSub) const { return Find(strSub.GetBuffer(0)); } // 获取缓冲区 char* CString::GetBuffer(int) { return (char*)m_str.c_str(); } // 获取只读缓冲区 const char* CString::GetBuffer(int) const { return m_str.c_str(); } void CString::Format(const char* pstrFormat, ...) { if (pstrFormat nullptr) { m_str.clear(); return; } va_list argList; va_start(argList, pstrFormat); // 1. 先复制一份用来计算长度 va_list argsCopy; va_copy(argsCopy, argList); int len vsnprintf(nullptr, 0, pstrFormat, argsCopy); va_end(argsCopy); if (len 0) { va_end(argList); // 这里必须结束主列表 m_str.clear(); return; } // 2. 再复制一份用来真正输出 std::unique_ptrchar[] buf(new char[len 1]); va_copy(argsCopy, argList); // ✅ 重新复制 vsnprintf(buf.get(), len 1, pstrFormat, argsCopy); va_end(argsCopy); // 最后结束主列表 va_end(argList); m_str buf.get(); } // 相等比较 bool CString::operator(const CString str) const { return m_str str.m_str; } // 不等比较 bool CString::operator!(const CString str) const { return m_str ! str.m_str; } // 与C字符串相等比较 bool CString::operator(const char* lpsz) const { if(!lpsz) return IsEmpty(); return m_str lpsz; } // 与C字符串不等比较 bool CString::operator!(const char* lpsz) const { return !(*this lpsz); } // 字符串拼接(CString CString) CString operator(const CString s1, const CString s2) { CString s; s.m_str s1.m_str s2.m_str; return s; } // 字符串拼接(CString C字符串) CString operator(const CString s1, const char* s2) { CString s; if(s2) { s.m_str s1.m_str s2; } else { s.m_str s1.m_str; } return s; } // 字符串拼接(C字符串 CString) CString operator(const char* s1, const CString s2) { CString s; if(s1) { s.m_str s1 s2.m_str; } else { s.m_str s2.m_str; } return s; } // 字符串拼接(CString 字符) CString operator(const CString s1, char ch) { CString s; s.m_str s1.m_str ch; return s; } // 去除左侧空白 void CString::TrimLeft() { size_t start m_str.find_first_not_of( \t\n\r); if(start std::string::npos) m_str.clear(); else m_str m_str.substr(start); } // 去除右侧空白 void CString::TrimRight() { size_t end m_str.find_last_not_of( \t\n\r); if(end std::string::npos) m_str.clear(); else m_str.erase(end 1); } // 去除左右空白 void CString::Trim() { TrimLeft(); TrimRight(); } // 转小写 void CString::MakeLower() { int len GetLength(); for (int i 0; i len; i) { m_str[i] tolower(m_str[i]); } } // 转大写 void CString::MakeUpper() { int len GetLength(); for (int i 0; i len; i) { m_str[i] toupper(m_str[i]); } } // 大于比较(CString) bool CString::operator(const CString str) const { return m_str str.m_str; } // 小于比较(CString) bool CString::operator(const CString str) const { return m_str str.m_str; } // 大于等于(CString) bool CString::operator(const CString str) const { return m_str str.m_str; } // 小于等于(CString) bool CString::operator(const CString str) const { return m_str str.m_str; } // 大于比较C字符串 bool CString::operator(const char* lpsz) const { if(!lpsz) return !IsEmpty(); return m_str lpsz; } // 小于比较C字符串 bool CString::operator(const char* lpsz) const { if(!lpsz) return false; return m_str lpsz; } // 大于等于C字符串 bool CString::operator(const char* lpsz) const { if(!lpsz) return !IsEmpty(); return m_str lpsz; } // 小于等于C字符串 bool CString::operator(const char* lpsz) const { if(!lpsz) return false; return m_str lpsz; }