CString类的完美总结:
①、CString 类对象的初始化:
CString str;
CString str1(_T("abc"));
CString str2 = _T("defg");
TCHAR szBuf[] = _T("kkk");
CString str3(szBuf);
CString str4 = szBuf;
TCHAR *p = _T("1k2");
//TCHAR * 转换为 CString
CString str5(p);
CString str6 = p;
CString str7(str1);
CString str8 = str7;
②、字符串基本操作:
● 长度:GetLength();
CString str(_T("abc"));
int len = str.GetLength(); //len == 3
● 是否为空,即不含字符:IsEmpty();
● 清空字符串:Empty();
CString str(_T("abc"));
BOOL mEmpty = str.IsEmpty(); //mEmpty == FALSE
str.Empty();
mEmpty = str.IsEmpty(); //mEmpty == TRUE
● 转换大小写:MakeUpper、MakeLower
● 转换顺序:MakeReverse
CString str(_T("Abc"));
str.MakeUpper(); //str == ABC
str.MakeLower(); //str == abc
str.MakeReverse(); //str == cba
● 字符串的连接:+、+=
CString str(_T("abc"));
str = _T("de") + str + _T("kp"); //str == deabckp
str += _T("123"); //str == deabckp123
TCHAR szBuf[] = _T("789");
str += szBuf; //str == deabckp123789
● 字符串的比较:==、!=、(<、>、<=、>= 不常用)、Compare(区分大小写)、CompareNoCase(不区分大小写)
CString str1(_T("abc"));
CString str2 = _T("aBc");
if (str1 == str2){
MessageBox(_T("str1 等于 str2"));
}else{
MessageBox(_T("str1 不等于 str2"));
}
③、字符串的查找:
Find、ReverseFind、FindOneOf 三个函数可以实现字符串的查找操作
Find 从指定位置开始查找指定的字符或者字符串,返回其位置,找不到返回 -1;
举例:
CString str(_T("abcdefg"));
int idx = str.Find(_T("cde"), 0); //idx 的值为2;
ReverseFind 从字符串末尾开始查找指定的字符,返回其位置,找不到返回 -1,虽然是从后向前查找,但是位置为从开始算起;
CString str(_T("abcdefg"));
int idx = str.ReverseFind('e'); //idx 的值为4;
FindOneOf 查找参数中给定字符串中的任意字符,返回第一次出现的位置,找不到返回 -1;
CString str(_T("abcabcd"));
int idx = str.FindOneOf(_T("cbd")); //idx 的值为1;
④、字符串的替换与删除:
Replace 替换 CString 对象中的指定的字符或者字符串,返回替换的个数,无匹配字符返回 0;
CString str(_T("abcdabc"));
int num = str.Replace('b', 'k'); //str == akcdakc, num == 2
CString str(_T("abcdabc"));
int num = str.Replace(_T("bc"), _T("kw")); //str == akwdakw, num == 2
Remove 删除 CString 对象中的指定字符,返回删除字符的个数,有多个时都会删除;
CString str(_T("abcdabcb"));
int num = str.Remove('b'); //str == acdac, num == 3
Delete 删除 CString 对象中的指定位置的字符,返回处理后的字符串长度;
CString str(_T("abcd"));
int num = str.Delete(1, 3); //str == a, num == 1
⑤、字符串的提取:
Left、Mid、Right 三个函数分别实现从 CString 对象的 左、中、右 进行字符串的提取操作;
CString str(_T("abcd"));
CString strResult = str.Left(2); //strResult == ab
strResult = str.Mid(1); //strResult == bcd
strResult = str.Mid(0, 2); //strResult == ab
strResult = str.Right(2); //strResult == cd
⑥、单个字符的修改:
GetAt、SetAt 可以获取与修改 CString 对象中的单个 TCHAR 类型字符;
操作符也可以获取 CString 对象中的单个字符,但为只读的,不能进行修改;
CString str(_T("abcd"));
str.SetAt(0, 'k'); //str == kbck
TCHAR ch = str.GetAt(2); //ch == c
⑦、其他类型与 CString 对象类型的转换:
● 格式化字符串:Format 方法,实现从 int、long 等数值类型、TCHAR、TCHAR * 等类型向 CString 类型的转换;
int num = 6;
CString str;
str.Format(_T("%d"), num);
● CString 类型向 int 等数值类型、TCHAR * 类型的转换:
TCHAR *pszBuf = str.GetBuffer();
str.ReleaseBuffer();
TCHAR *p = (LPTSTR)(LPCTSTR)str;
CString str1(_T("123"));
int num = _ttoi(str1);
⑧、CString 对象的 Ansi 与 Unicode 转换:
大家可以直接使用上节课给大家讲解的方法,此外这里给大家介绍一种从 Ansi 转换到 Unicode 的隐含方法:
//当前工程环境为Unicode
CString str;
str = "abc";
char *p = "defg";
str = p;
⑨、 CString 对象字符串所占用的字节数:
CString str = _T("abc");
错误的求法:sizeof(CString)、sizeof(str)
正确的求法:str.GetLength()*sizeof(TCHAR)
⑩、当作为 TCHAR * 类型传参时,确保申请了足够用的空间,比如使用 GetModuleFileName 函数;
CString的构造函数
CString( );例:CString csStr;
CString( const CString& stringSrc );
例:CString csStr("ABCDEF中文123456");
CString csStr2(csStr);
CString( TCHAR ch, int nRepeat = 1 );
例:CString csStr('a',5);
//csStr="aaaaa"
CString( LPCTSTR lpch, int nLength );
例:CString csStr("abcdef",3);
//csStr="abc"
CString( LPCWSTR lpsz );
例:wchar_t s[]=L"abcdef";
CString csStr(s);
//csStr=L"abcdef"
CString( const unsigned char* psz );
例:const unsigned char s[]="abcdef";
const unsigned char* sp=s;
CString csStr(sp);
//csStr="abcdef"
CString( LPCSTR lpsz );
例:CString csStr("abcdef");
//csStr="abcdef"
返回字符串的长度,不包含结尾的空字符。
例:csStr="ABCDEF中文123456";
printf("%d",csStr.GetLength()); //16
颠倒字符串的顺序
例:csStr="ABCDEF中文123456";
csStr.MakeReverse();
cout<<csStr; //654321文中FEDCBA
将小写字母转换为大写字母
例:csStr="abcdef中文123456";
csStr.MakeUpper();
cout<<csStr; //ABCDEF中文123456
将大写字母转换为小写字母
例:csStr="ABCDEF中文123456";
csStr.MakeLower();
cout<<csStr; //abcdef中文123456
区分大小写比较两个字符串,相等时返回0,大于时返回1,小于时返回-1
例:csStr="abcdef中文123456";
csStr2="ABCDEF中文123456";
cout<<csStr.CompareNoCase(csStr2); //0
不区分大小写比较两个字符串,相等时返回0,大于时返回1,小于时返回-1
例:csStr="abcdef中文123456";
csStr2="ABCDEF中文123456";
cout<<csStr.CompareNoCase(csStr2); //-1
删除字符,删除从下标nIndex开始的nCount个字符
例:csStr="ABCDEF";
csStr.Delete(2,3);
cout<<csStr; // ABF
//当nIndex过大,超出对像所在内存区域时,函数没有任何操作。
//当nIndex为负数时,从第一个字符开始删除。
//当nCount过大,导致删除字符超出对像所在内存区域时,会发生无法预料的结果。
//当nCount为负数时,函数没有任何操作。
int Insert( int nIndex, LPCTSTR pstr )
在下标为nIndex的位置,插入字符或字符串。返回插入后对象的长度
例:csStr="abc";
csStr.Insert(2,'x');
cout<<csStr; //abxc
csStr.Insert(2,"xyz");
cout<<csStr; //abxyzc
//当nIndex为负数时,插入在对象开头
//当nIndex超出对象末尾时,插入在对象末尾
移除对象内的指定字符。返回移除的数目
例:csStr="aabbaacc";
csStr.Remove('a');
cout<<csStr; //bbcc
int Replace( LPCTSTR lpszOld, LPCTSTR lpszNew );
替换字串
例:csStr="abcdef";
csStr.Replace('a','x');
cout<<csStr; //xbcdef
csStr="abcdef";
csStr.Replace("abc","xyz");
cout<<csStr; //xyzdef
void TrimLeft( TCHAR chTarget );
void TrimLeft( LPCTSTR lpszTargets );
从左删除字符,被删的字符与chTarget或lpszTargets匹配,一直删到第一个不匹配的字符为止
例:csStr="aaabaacdef";
csStr.TrimLeft('a');
cout<<csStr; //baacdef
csStr.TrimLeft("ab");
cout<<csStr; //cdef
//无参数时删除空格
void TrimRight( TCHAR chTarget );
void TrimRight( LPCTSTR lpszTargets );
从右删除字符,被删的字符与chTarget或lpszTargets匹配,一直删到第一个不匹配的字符为止
例:csStr="abcdeaafaaa";
csStr.TrimRight('a');
cout<<csStr; //abcdeaaf
csStr="abcdeaafaaa";
csStr.TrimRight("fa");
cout<<csStr; //abcde
//无参数时删除空格
清空
例:csStr="abcdef";
csStr.Empty();
printf("%d",csStr.GetLength()); //0
测试对象是否为空,为空时返回零,不为空时返回非零
例:csStr="abc";
cout<<csStr.IsEmpty(); //0;
cout<<csStr.IsEmpty(); //1;
int Find( LPCTSTR lpszSub ) const;
int Find( TCHAR ch, int nStart ) const;
int Find( LPCTSTR pstr, int nStart ) const;
查找字串,nStart为开始查找的位置。未找到匹配时返回-1,否则返回字串的开始位置
例:csStr="abcdef";
cout<<csStr.Find('b'); //1
cout<<csStr.Find('b',3); //-1
cout<<csStr.Find('b',0); //1
cout<<csStr.Find("de",4); //-1
cout<<csStr.Find("de",0); //3
//当nStart超出对象末尾时,返回-1。
//当nStart为负数时,返回-1。
查找lpszCharSet中任意一个字符在CString对象中的匹配位置。未找到时返回-1,否则返回字串的开始位置
例:csStr="abcdef";
cout<<csStr.FindOneOf("cxy"); //2
返回对象中与lpszCharSet中任意匹配的第一个字符之前的子串
例:csStr="abcdef";
cout<<csStr.SpanExcluding("cf"); //ab
从对象中查找与lpszCharSe中任意字符不匹配的字符,并返回第一个不匹配字符之前的字串
例:csStr="abcdef";
cout<<csStr.SpanIncluding("fdcba"); //abcd
从后向前查找第一个匹配,找到时返回下标。没找到时返回-1
例:csStr="abba";
cout<<csStr.ReverseFind('a'); //3
void Format( UINT nFormatID, ... );
格式化对象,与C语言的sprintf函数用法相同
例:csStr.Format("%d",13);
cout<<csStr; //13
返回下标为nIndex的字符,与字符串的[]用法相同
例:csStr="abcdef";
cout<<csStr.GetAt(2); //c
//当nIndex为负数或超出对象末尾时,会发生无法预料的结果。
给下标为nIndex的字符重新赋值
例:csStr="abcdef";
csStr.SetAt(2,'x');
cout<<csStr; //abxdef
//当nIndex为负数或超出对象末尾时,会发生无法预料的结果。
从左取字串
例:csStr="abcdef";
cout<<csStr.Left(3); //abc
//当nCount等于0时,返回空。
//当nCount为负数时,返回空。
//当nCount大于对象长度时,返回值与对象相同。
从右取字串
例:csStr="abcdef";
cout<<csStr.Right(3); //def
//当nCount等于0时,返回空。
//当nCount为负数时,返回空。
//当nCount大于对象长度时,返回值与对象相同。
CString Mid( int nFirst, int nCount ) const;
从中间开始取字串
例:csStr="abcdef";
cout<<csStr.Mid(2); //cdef
cout<<csStr.Mid(2,3); //cde
//当nFirst为0和为负数时,从第一个字符开始取。
//当nFirst等于对象末尾时,返回空字串。
//当nFirst超出对象末尾时,会发生无法预料的结果。
//当nCount超出对象末尾时,返回从nFirst开始一直到对象末尾的字串
//当nCount为0和为负数时,返回空字串。
申请新的空间,并返回指针
例:csStr="abcde";
LPTSTR pStr=csStr.GetBuffer(10);
strcpy(pStr,"12345");
csStr.ReleaseBuffer();
pStr=NULL;
cout<<csStr //12345
//使用完GetBuffer后,必须使用ReleaseBuffer以更新对象内部数据,否则会发生无法预料的结果。
使用GetBuffer后,必须使用ReleaseBuffer以更新对象内部数据
例:csStr="abc";
LPTSTR pStr=csStr.GetBuffer(10);
strcpy(pStr,"12345");
cout<<csStr.GetLength(); //3(错误的用法)
csStr.ReleaseBuffer();
cout<<csStr.GetLength(); //5(正确)
//CString对象的任何方法都应在ReleaseBuffer之后调用
申请新的空间,并返回指针
例:csStr="abc";
csStr.GetBufferSetLength(20);
cout<<csStr; //abc
count<<csStr.GetLength(); //3;
//使用GetBufferSetLength后可以不必使用ReleaseBuffer。
string 与 CString 转化:
都通过基本类型来转换即可:
CString可以转换为基本类型LPCTSTR,LPCTSTR根据项目编码可以是const char*或者const wchar_t*;string可以用c_str()转换为const char*,stringw可以用c_str()转换为const w_char*。而CString和string/w都重载了=赋值操作符,可以把char*或者wchar_t*字符串赋值给CString或者string/w类型的变量,或者调用其构造函数。
string to CString比较简单
string str="abcde";
CString cstr(str.c_str());
CString to string,要看你的CString用的是UNICODE还是非UNICODE,
非UNICODE就简单了
CString cs="abcde";
string str(cs.GetBuffer(cs.GetLength()));
UNICODE就麻烦点
需要转换一下才行,给个函数你用
CString cs=_T("abcde");
string str=CGeneralUtility::WChar2Ansi(cs.GetBuffer(cs.GetLength()));
string CUtility::WChar2Ansi(LPCWSTR pwszSrc)
{
int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
if (nLen<= 0) return std::string("");
char* pszDst = new char[nLen];
if (NULL == pszDst) return std::string("");
WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
pszDst[nLen -1] = 0;
std::string strTemp(pszDst);
delete [] pszDst;
return strTemp;
}
1,string -> CString
CString.format("%s", string.c_str());
2,char -> string
string s(char *);
3,CString -> string
string s(CString.GetBuffer());
GetBuffer()后一定要ReleaseBuffer(),否则就没有释放缓冲区所占的空间.
<string><string.h> 和<cstring>的区别
#include <string.h >
void main()
{
string aaa = " abcsd d " ;
printf( " looking for abc from abcdecd %s\n " ,
(strcmp(aaa, " abc " )) ? " Found " : " Not Found " );
}
不能正确执行,提示说是string类型没有定义
而下面:
#include <string>
using namespace std;
void main()
{
string aaa = " abcsd d " ;
printf( " looking for abc from abcdecd %s\n " ,
(strcmp(aaa, " abc " )) ? " Found " : " Not Found " );
}
这里的string编译器就认识了,但是strcmp就不认识了呢?
一般一个C++的老的带“。h”扩展名的库文件,比如iostream.h,在新标准后的标准库中都有一个不带“。h”扩展名的相对应,区别除了后者的好多改进之外,还有一点就是后者的东东都塞进了“std”名字空间中。
但唯独string特别。
问题在于C++要兼容C的标准库,而C的标准库里碰巧也已经有一个名字叫做“string.h”的头文件,包含一些常用的C字符串处理函数,比如楼主提到的strcmp.
这个头文件跟C++的string类半点关系也没有,所以<string>并非<string.h>的“升级版本”,他们是毫无关系的两个头文件。
要达到楼主的目的,比如同时:
#include <string .h>或者
#include <string>
using namespace std;
#include < cstring >其中<cstring>是与C标准库的<string.h>相对应,但裹有std名字空间的版本。
#include < string >
笑谈(来自高质量++)
C++标准库很大。非常大。难以置信的大。怎么个大法?这么说吧:在C++标准中,关于标准库的规格说明占了密密麻麻300 多页,这还不包括标准C 库,后者只是"作为参考"(老实说,原文就是用的这个词)包含在C++库中。当然,并非总是越大越好,但在现在的情况下,确实越大越好,因为大的库会包含大量的功能。标准库中的功能越多,开发自己的应用程序时能借助的功能就越多。C++库并非提供了一切(很明显的是,没有提供并发和图形用户接口的支持),但确实提供了很多。几乎任何事你都可以求助于它。在归纳标准库中有些什么之前,需要介绍一下它是如何组织的。因为标准库中东西如此之多,你(或象你一样的其他什么人)所选择的类名或函数名就很有可能和标准库中的某个名字相同。为了避免这种情况所造成的名字冲突,实际上标准库中的一切都被放在名字空间std 中(参见条款28)。但这带来了一个新问题。无数现有的C++代码都依赖于使用了多年的伪标准库中的功能,例如,声明在<iostream.h>,<complex.h>,<limits.h>等头文件中的功能。现有软件没有针对使用名字空间而进行设计,如果用std 来包装标准库导致现有代码不能用,将是一种可耻行为。(这种釜底抽薪的做法会让现有代码的程序员说出比"可耻" 更难听的话)慑于被激怒的程序员会产生的破坏力,标准委员会决定为包装了std 的那部分标准库构件创建新的头文件名。生成新头文件的方法仅仅是将现有C++头文件名中的。h 去掉,方法本身不重要,正如最后产生的结果不一致也并不重要一样。所以<iostream.h>变成了<iostream>,<complex.h>变成了<complex>,等等。对于C 头文件,采用同样的方法,但在每个名字前还要添加一个c.所以C 的<string.h>变成了<cstring>,<stdio.h>变成了<cstdio>,等等。最后一点是,旧的C++头文件是官方所反对使用的(即,明确列出不再支持),但旧的C 头文件则没有(以保持对C 的兼容性)。实际上,编译器制造商不会停止对客户现有软件提供支持,所以可以预计,旧的C++头文件在未来几年内还是会被支持。
所以,实际来说,下面是C++头文件的现状:
旧的C++头文件名如<iostream.h>将会继续被支持,尽管它们不在官方标准中。这些头文件的内容不在名字空间std 中。
新的C++头文件如<iostream>包含的基本功能和对应的旧头文件相同,但头文件的内容在名字空间std 中。(在标准化的过程中,库中有些部分的细节被修改了,所以旧头文件和新头文件中的实体不一定完全对应。)
标准C 头文件如<stdio.h>继续被支持。头文件的内容不在std 中。
具有C 库功能的新C++头文件具有如<cstdio>这样的名字。它们提供的内容和相应的旧C 头文件相同,只是内容在std 中。
所有这些初看有点怪,但不难习惯它。最大的挑战是把字符串头文件理清楚:
<string.h>是旧的C 头文件,对应的是基于char*的字符串处理函数;
<cstring>是对应于旧C 头文件的std 版本;
<string>是包装了std 的C++头文件,对应的是新的string 类。
CString
CString does not have a base class.
A CString object consists of a variable-length sequence of characters. CString provides functions and operators using a syntax similar to that of Basic. Concatenation and comparison operators, together with simplified memory management, make CStringobjects easier to use than ordinary character arrays.
CString is based on the TCHAR data type. If the symbol _UNICODE is defined for your program, TCHAR is defined as typewchar_t, a 16-bit character type; otherwise, it is defined as char, the normal 8-bit character type. Under Unicode, then,CString objects are composed of 16-bit characters. Without Unicode, they are composed of 8-bit char type.
When not using _UNICODE, CString is enabled for multibyte character sets (MBCS, also known as double-byte character sets, DBCS). Note that for MBCS strings, CString still counts, returns, and manipulates strings based on 8-bit characters, and your application must interpret MBCS lead and trail bytes itself.
CString objects also have the following characteristics:
-
CString objects can grow as a result of concatenation operations.
-
CString objects follow “value semantics.” Think of a CString object as an actual string, not as a pointer to a string.
- You can freely substitute CString objects for const char* and LPCTSTR function arguments.
- A conversion operator gives direct access to the string’s characters as a read-only array of characters (a C-style string).
Tip Where possible, allocate CString objects on the frame rather than on the heap. This saves memory and simplifies parameter passing.
CString assists you in conserving memory space by allowing two strings sharing the same value also to share the same buffer space. However, if you attempt to change the contents of the buffer directly (not using MFC), you can alter both strings unintentionally. CString provides two member functions, CString::LockBuffer and CString::UnlockBuffer, to help you protect your data. When you call LockBuffer, you create a copy of a string, then set the reference count to -1, which "locks" the buffer. While the buffer is locked, no other string can reference the data in that string, and the locked string will not reference another string. By locking the string in the buffer, you ensure that the string’s exclusive hold on the data will remain intact. When you have finished with the data, call UnlockBuffer to reset the reference count to 1.
For more information, see the https://msdn.microsoft.com/en-us/library/aa296565(v=vs.60).aspx and articles in Visual C++ Programmer’s Guide and https://msdn.microsoft.com/en-us/library/2ewd52wf(v=vs.60).aspx in the Run-Time Library Reference.
#include <afx.h>
Class Members | Hierarchy Chart
Sample https://msdn.microsoft.com/en-us/library/ms386443(v=vs.60).aspx
See Also In Visual C++ Programmer’s Guide: , , https://msdn.microsoft.com/en-us/library/aa296561(v=vs.60).aspx , ,