1. 主页 > 好文章

MFC开发必备:CString类10个高频方法应用指南


你还在为字符串处理掉头发吗?

(拍大腿)哎,刚学MFC那会儿,我对着满屏的char*和wchar_t发愁啊!直到遇见CString——这玩意儿简直就是Windows开发的"瑞士军刀"。今天咱们不说虚的,直接上硬菜,手把手教你10个必杀技!


招式一:初始化三连(别只会用等号!)

新手最爱写的代码:CString str = _T("hello")。其实啊,??CString有8种构造姿势??,比如说:

  • 用数字初始化:CString str(100) → "100"
  • 截取字符串:CString str("abcdef",3) → "abc"
  • 重复字符:CString str('*',5) → "????*"

(敲黑板)重点来了!??带_T的宽字符初始化才是正道??,不然遇到中文分分钟乱码给你看!


招式二:Format玩出花(告别sprintf!)

你们是不是经常写这种代码?

cpp复制
int id = 10086;
char buffer[256];
sprintf(buffer, "用户ID:%d", id);

(扶额)这都2023年了!试试??CString的Format魔法??:

cpp复制
CString str;
str.Format(_T("用户:%s | 余额:%.2f元"), _T("张三"), 158.6);
// 输出:用户:张三 | 余额:158.60元

(划重点)??占位符对照表??收好:

  • %s 字符串 → 记得用_T包裹
  • %d 整数 → 比char*省心多了
  • %I64d 处理大整数 → 再也不怕溢出!

招式三:GetBuffer的正确姿势(小心内存泄漏!)

遇到过这种报错吗?Debug Assertion Failed! Buffer...。这就是??GetBuffer/ReleaseBuffer没配对使用??的后果!

正确操作:

cpp复制
CString str;
LPTSTR pBuf = str.GetBuffer(256);  // 申请256字符空间
_stprintf_s(pBuf, 256, _T("当前温度:%d℃"), 28);
str.ReleaseBuffer();  // 这句不写,程序分分钟崩溃!

(掏心窝子说)??三个必记原则??:

  1. GetBuffer后必须ReleaseBuffer
  2. 别在GetBuffer后直接操作原字符串
  3. 缓冲区大小宁大勿小

招式四:Trim去空白(用户输入必备)

用户注册时总有人手滑输空格对吧???Trim系列三剑客??来救场:

cpp复制
str.TrimLeft();    // 干掉左边空白
str.TrimRight();   // 干掉右边空白 
str.Trim();        // 两头一起清

(举个栗子)用户输入" 123 " → Trim后变"123"。??注意啦??:这方法对中文全角空格无效,得用自定义过滤!


招式五:Find查位置(别再用strstr了!)

找子字符串还在用C语言的strstr???CString.Find更智能??:

cpp复制
int pos = str.Find(_T("bug"));
if(pos != -1){
    // 找到bug的位置了!
}

(神技巧)??反向查找??你试过吗?ReverseFind方法从后往前找,定位文件扩展名超方便:

cpp复制
CString path = _T("report.docx");
int dotPos = path.ReverseFind('.');
// 轻松拿到.docx后缀

招式六:Replace大法(路径处理神器)

遇到过要把反斜杠换成斜杠吗???Replace一招搞定??:

cpp复制
CString path = _T("C:\\Program Files\\App");
path.Replace(_T('\\'), _T('/'));
// 变成"C:/Program Files/App"

(冷知识)这个方法??支持批量替换??,比如把"&"替换成"&"防XSS攻击,超实用!


招式七:Compare比大小(告别==运算符)

直接写if(str1 == str2)???小心踩坑??!正确姿势:

cpp复制
if(str1.Compare(str2) == 0)  // 完全匹配
if(str1.CompareNoCase(str2) == 0) // 不分大小写

(血泪教训)曾经因为==比较失败,导致用户登录死活不成功,查了三天才发现是大小写问题!


招式八:Mid截取子串(比substr强在哪?)

想要截取身份证中的生日信息???Mid/Left/Right三连击??:

cpp复制
CString idCard = _T("110101199003077856");
CString birthday = idCard.Mid(6,8); // 从第6位取8位 → 19900307

(重点提示)??索引从0开始??!很多人在这里栽跟头,记住了啊!


招式九:GetLength判空(别用empty()!)

检测字符串是否为空,新手爱用str.IsEmpty()。其实??GetLength更直接??:

cpp复制
if(str.GetLength() > 0){
    // 处理非空字符串
}

(特殊场景)处理二进制数据时,GetLength能返回包含'\0'的真实长度,这个IsEmpty可做不到!


招式十:转换操作(打通任督二脉)

最让人头大的编码转换,??CA2W/CT2A来帮忙??:

cpp复制
// ANSI转Unicode
CStringA strA = "Hello";
CStringW strW = CA2W(strA);

// Unicode转UTF8
CString str = _T("你好");
CStringA utf8Str = CT2A(str, CP_UTF8); 

(避坑指南)转换时??务必指定代码页??,特别是中文环境要用CP_UTF8或CP_ACP!


个人私货时间

用了这么多年CString,我觉得微软这个类最牛的地方在于??自动内存管理??。不像char*总要担心缓冲区溢出,也不像STL string在MFC里水土不服。不过啊(小声说),遇到超大数据量还是得用CStringT,普通CString处理百万级字符串确实会卡。

最后送大家一句话:??字符串处理是基本功??,把这些方法吃透了,至少能少写30%的bug。下次碰到字符串问题,先别急着百度,把这篇文章翻出来看看,说不定答案就在里面呢!

本文由嘻道妙招独家原创,未经允许,严禁转载