#ifdef _unicode #define _t l
2 i6 x l1 x$ P! ?* F$ `) P' C# K #else3 Q y7 z! a# v$ t- U! g0 l
#define _t
- ?6 e7 ~6 P+ t' n3 x$ e0 Y #endif
. c+ H3 X9 m1 t7 r+ c8 ~ these data-type mappings are defined in tchar.h and depend on whether the constant _unicode or _mbcs has been defined in your program.6 G' ^* D3 C. ]) ?( e, m' w2 @
当我们在利用cstring 类便捷性时,有些特殊化的东西无法做,于是相互之间的转换变经常被需要:
& T6 j6 y( m+ F0 |3 q; v* F 在转换之前必须确保你的字符的范围在你的范围之内。7 n; ?9 D4 y7 e' y
1.cstirng转 char *
% }% L3 J; U) _% R `5 k' b$ t 传给未分配内存的指针.
- p5 E+ j5 w2 V- V s cstring cstr1="abcd";
, p3 `- W l* Y1 ] char * ch=cstr1.getbuffer(cstr1.getlength()+1); //获取指向cstring最后一个字符的地址。
: ~" c3 A1 s* G8 q: i; d- V [ cstr1.releasebuffer();
) r7 ?6 R# q( x' w. B 注意:用完ch后,不用delete ch,因为这样会破坏cstr内部空间,容易造成程序崩溃.% v! G5 T; Y# w3 A
getbuffer :这个函数是为一个cstring对象重新获取其内部字符缓冲区的指针,返回的lptstr为非const的,从而允许直接修改cstring中的内容! 如果nminbuflength 比当前buffer大,那么就调用releasebuffer函数去释放当前的buffer,用一个被请求的大小去覆盖这个buffer.
" ?5 _0 ^2 i" y e 而getbuffer则是返回一个可以供调用者写入的内存,并且,你可以给定大小。其实它就相当于申请一块nlen大小的内存,只不过,这块内存是被引用在cstring对象的内部而已,这是非常有效的一种用法,如果不直接用getbuffer函数来申请的话,那么你必须用new操作符(或者 malloc()函数)在cstring的外部申请,然后再将申请的内存拷贝到cstring对象中,显然这是一个非常冗余的操作,会使你函数的效率大大下降。
# u' j2 r6 ?& m7 m- b releasebuffer函数是用来告诉cstring对象,你的getbuffer所引用的内存已经使用完毕,现在必须对它进行封口,否则 cstring将不会知道它现在所包含的字符串的长度,所以在使用完getbuffer之后,必须立即调用releasebuffer函数重置 cstring的内部属性,其实也就是头部信息。
" p$ @; t |* f9 m/ g4 m 值赋给已分配内存的char *
- \# ]1 V% o: x9 ^ cstring cstr1 = "asddsd";* x6 O5 ?% T$ t) N# U
int strlength = cstr1.getlength() + 1;
9 d7 ~1 P Q: w' s( Q4 z& [ char *pvalue = new char[strlength];6 ? [4 P/ n( n: m" n1 x
strncpy(pvalue, cstr1, strlength);
7 A2 V9 I3 V- e) |) P2 d% w 赋值:
/ a: v+ ]/ _. i6 d R3 T9 J char* psz = “joise”; 没有构造函数,仅可以赋值(因为它本身就是基本型)( @" w& A( e2 T2 }5 w& {3 a
cstring cstr( psz ); 可以从基本的一些字符串变量构造而来,包括char*等3 ^ B( e3 V$ I! Q
string str( cstr ); 可以从几乎所有的字符串构造而来,包括cstring和char*;( i8 ]8 T- }+ D7 C2 N, t
以上也可以看作由 char *转cstirng的办法。
) ]) `0 E( g5 C( B+ J& {# a7 Q W8 L6 M8 ]) ^1 y# x
字符串非常非常常见又重要,而且还有那么多名堂在里面( B& V4 f( I0 S; N5 R) r6 }
字符串:
* }, a8 j2 f% _, X, n 在标准c中,是没有字符串变量的,但是有字符数组。而且标准c带有的标准库函数:string.h中包含了大量的字符串操作函数,当然如果必要的话,你也可以自己写代码实现这些函数的功能。我认为即便c语言再简单,即便这些知识看起来是多么枯燥和简单,依然有必要回顾并牢记它们:9 B w( T5 @6 q8 r
对于32位操作系统! U( w8 N3 h' g* l: a
int (2字节) short (1字节) long(4字节)
+ r2 O. K+ f6 P: F& | unsigned char 从0到256之间
) N0 N/ P$ J8 d S% M char 从-128到127之间4 N+ a4 H" h( X$ ~7 _
byte 字节就是无符号的字符
5 t" q) ]$ {5 W, K- _+ H# w unicode:两字节的字符
" M* w; i+ w/ |% F3 u 由此可见:byte=nusigned char, short=char
! x# t8 ], \1 \: B- x' O2 E char* :是指向ansi字符数组的指针,其中每个字符占据8位(有效数据是除掉最高位的其他7位),这里保持了与传统的c,c++的兼容。
: ?2 ~0 z+ E, {$ e1 P& w tchar: 在采用unicode方式编译时是wchar_t,在普通时编译成char. 如果定义_unicode,声明如 :typedef wchar_t tchar; 如果没有定义_unicode,则声明如:typedef char tchar;0 v' a- ^6 m+ |0 y( d
lpstr: 是一个指向以‘\0’结尾的ansi字符数组的指针,与char*可以互换使用,在win32中较多地使用lpstr。1 N ?+ y. H( F' m7 Q8 J
lptstr和lpctstr:中的含义就是每个字符是这样的tchar。
* H1 i" K7 o, r9 ?' T3 a) o, |4 k lpwstr与lpcwstr:类似于lpstr与lpcstr,只是字符数据是16位的wchar_t而不是char。
, Z' k3 }( H! J: H# H; W lpcstr: 增加的‘c’的含义是“constant”(常量),表明这种数据类型的实例不能被使用它的api函数改变,除此之外,它与lpstr是等同的。
7 l. s8 R# S. F& x lpctstr:* W1 b4 q7 x0 ?& ]) {
#ifdef _unicode; h" {4 Q5 o, ]* M3 R# ^+ C1 C
typedef const wchar_t * lpctstr;
: q# c/ J- {* \5 P1 O; K #else4 h( t. B1 Z2 ?4 A" `! M, x
typedef const char * lpctstr;4 W8 @2 u0 b* Q' Y5 G
#endif& s6 h0 M( q8 O2 l9 r7 \
cstring类, 是由微软公司集成在vc的mfc里面,包含字符串各种常见操作的类。其源码可以在mfc里面找到。
: S, j+ ?- r3 Z! { 当声明一个字符串变量,首先会调用构造函数,在成功后,便可利用它的常见操作。
% Z: A, L: B( N9 L cstring 是一个完全独立的类,动态的tchar数组,封装了 + 等操作符和字符串操作方法。8 t4 e5 n! t" P! `8 `6 p- Y
1、ansi(即mbcs):为多字节字符集,它是不定长表示世界文字的编码方式。
, B8 _3 s4 X4 m! C. }+ ~ 2、unicode:用两个字节表示一个字符的编码方式。: Y! a1 n7 u& a$ B& A; ~
mbcs宏对应的字符串指针为lpstr,unicode对应的指针为lpwstr。lpstr被定义成是一个指向以null(‘\0’)结尾的8位ansi字符数组指针,而lpwstr是一个指向以null结尾的16位双字节字符数组指针。
4 x: X* j, \. }( n! j) U3 Y! Z
) A: t' o5 \8 b) Q% O$ t/ G 为了写程序的方便,微软定义了类型lptstr,在mbcs下它表示lpstr,在unicode下它表示lpwstr,这就可以重定义一个宏进行不同字符集的转换了。 |