C++ 字符串操作初析
曾經(jīng)有一篇關(guān)于C++程序?qū)懽鞯奈恼拢恼抡fC++程序員要花費(fèi)20%的時間來處理字符串方面的細(xì)節(jié)問題,甚至更多。可見C++中的字符處理是相當(dāng)復(fù)雜,原因是C++中有著豐富的字符及字符串類,如STL中的string,wstring,char,wchar_t、還有windows C程序?qū)懽髦蠵TSTR,PWSTR,PTSTR,MFC及ATL中的CString, BSTR,_bstr_t,CComBSTR,OLESTR,還有一種隨編譯時是否預(yù)定義了UNICODE而被分析為具體類型的TCHAR及這些字符,或封裝類的一大把函數(shù)。而我們要用的系統(tǒng)函數(shù),標(biāo)準(zhǔn)庫函數(shù)或其它庫函數(shù)。有的要這種字符而沒有提供接受其它字符的版本。這些原因也就促使了C++程序員往往要花許多的時間來處理字符串。上次和朋友聊到寫代碼的話題。他說一天只能寫三百來行的代碼。確實(shí)要寫高效的,高質(zhì)量的C++代碼很要下一番功夫。
在上面介紹了許多的字符串,及字符串封裝類。實(shí)際上所有的這些類都最終可歸結(jié)為C風(fēng)格字符串,也就是字符數(shù)組。目前字符的編碼方案主要有單字節(jié)字符(ANSI)編碼,多字節(jié)字符(MBCS)編碼,還有就是UNICODE編碼。前兩種字符編碼的字符還都是用char這個數(shù)據(jù)類型來維護(hù)。當(dāng)是多字節(jié)時典型的就是2個字節(jié)時,就會用2個char來存儲,一個字節(jié)時就會用一個char來存儲。這就是串中的字符占多少個字節(jié)得看具體的字符,不能像原來一樣一個一個地數(shù)就可以知道會占多少個字節(jié)。UNICODE則簡化了這種編碼方案,讓每個字符都占用相同大小的字節(jié),UNICODE 中的字符是用wchar_t來定義的,這中編碼方案則是每個字符都占用兩個字節(jié)。在這種編碼方案下我們又可以一個一個地數(shù)來算出占用了多少字節(jié),計算機(jī)可以用一種統(tǒng)計方式來處理這種字符串了。雖然犧牲了些內(nèi)存,但換取了邏輯的簡單性。
這里我寫了幾個工具函數(shù),可以方便地在各種數(shù)據(jù)類型之間進(jìn)行轉(zhuǎn)換。我認(rèn)為這幾個函數(shù)會對處理字符串提供幫助,所在我就在首頁發(fā)表了。大家有什么好的想法可以回復(fù)我。另我這兩天會封裝MSXML來操作XML,希望大家能給點(diǎn)意見。到時我可以與相關(guān)參與的人員共享這個封裝。


1
/**//**//**///////////////////////////////////////////////////////////////////////////
2
// Module: stringutility.h
3
// Conversion among wchar_t, char and TCHAR
4
//
5
/**//**//**///////////////////////////////////////////////////////////////////////////
6
#ifndef _STRINGUTILITY_H_
7
#define _STRINGUTILITY_H_
8
9
/**//**//**///////////////////////////////////////////////////////////////////////////
10
// get PSTR by PWSTR
11
// This function malloc some memory and you must free it
12
inline char* newPSTRFromPWSTRT(PWSTR source)
13

{
14
char *pCh = NULL;
15
int nLength = 0;
16
if(!source)
17
{
18
pCh = new char[1];
19
}
20
else
21
{
22
nLength= wcslen(source);
23
pCh = new char[2 * nLength + 1];
24
WideCharToMultiByte(CP_ACP,
25
0,
26
source,
27
-1,
28
pCh,
29
nLength * 2,
30
NULL,
31
NULL);
32
}
33
pCh[2 * nLength] = '\0';
34
return pCh;
35
}
36
37
/**//**//**///////////////////////////////////////////////////////////////////////////
38
// get PWSTR by PSTR
39
// This function malloc some memory and you must free it
40
inline wchar_t* newPWSTRFromPSTR(PSTR source)
41

{
42
wchar_t *pCh = NULL;
43
int nLength = 0;
44
if(!source)
45
{
46
pCh = new wchar_t[1];
47
}
48
else
49
{
50
nLength = strlen(source);
51
pCh = new wchar_t[nLength + 1];
52
MultiByteToWideChar(CP_ACP,
53
0,
54
source,
55
-1,
56
pCh,
57
nLength);
58
}
59
pCh[nLength] = '\0';
60
return pCh;
61
}
62
63
/**//**//**///////////////////////////////////////////////////////////////////////////
64
// get PSTR by PTSTR
65
// This function malloc some memory and you must free it
66
67
inline char* newPSTRFromPTSTR(PTSTR source)
68

{
69
#ifdef UNICODE
70
return newPSTRFromPWSTRT(source);
71
#else
72
char* pCh;
73
int iLength = 0;
74
if(!source)
75
{
76
pCh = new char[1];
77
}
78
else
79
{
80
iLength = strlen(source);
81
pCh = new char[iLength +1];
82
strcpy(pCh, source);
83
}
84
pCh[iLength] = '\0';
85
return pCh;
86
#endif
87
}
88
89
/**//**//**///////////////////////////////////////////////////////////////////////////
90
// get PWSTR by PTSTR
91
// This function malloc some memory and you must free it
92
93
inline wchar_t* newPWSTRFromPTSTR(PTSTR source)
94

{
95
#ifdef UNICODE
96
wchar_t *pCh = NULL;
97
int nLength = 0;
98
if(!source)
99
{
100
pCh = new wchar_t[1];
101
}
102
else
103
{
104
nLength = wcslen(source);
105
pCh = new wchar_t[nLength + 1];
106
wcscpy(pCh, source);
107
}
108
pCh[nLength] = L'\0';
109
return pCh;
110
#else
111
return newPWSTRFromPTSTR(source);
112
#endif
113
}
114
115
116
/**//**//**///////////////////////////////////////////////////////////////////////////
117
// get PTSTR by PSTR
118
// This function malloc some memory and you must free it
119
inline TCHAR* newPTSTRFromPSTR(PSTR source)
120

{
121
#ifdef UNICODE
122
return newPWSTRFromPSTR(source);
123
#else
124
return newPSTRFromPTSTR(source);
125
#endif
126
}
127
128
/**//**//**///////////////////////////////////////////////////////////////////////////
129
// get PTSTR by PWSTR
130
// This function malloc some memory and you must free it
131
inline TCHAR* newPTSTRFromPWSTR(PWSTR source)
132

{
133
#ifdef UNICODE
134
return newPWSTRFromPTSTR(source);
135
#else
136
return newPSTRFromPWSTRT(source);
137
#endif
138
}
139
#endif // end of #ifndef _STRINGUTILITY_H_
在上面介紹了許多的字符串,及字符串封裝類。實(shí)際上所有的這些類都最終可歸結(jié)為C風(fēng)格字符串,也就是字符數(shù)組。目前字符的編碼方案主要有單字節(jié)字符(ANSI)編碼,多字節(jié)字符(MBCS)編碼,還有就是UNICODE編碼。前兩種字符編碼的字符還都是用char這個數(shù)據(jù)類型來維護(hù)。當(dāng)是多字節(jié)時典型的就是2個字節(jié)時,就會用2個char來存儲,一個字節(jié)時就會用一個char來存儲。這就是串中的字符占多少個字節(jié)得看具體的字符,不能像原來一樣一個一個地數(shù)就可以知道會占多少個字節(jié)。UNICODE則簡化了這種編碼方案,讓每個字符都占用相同大小的字節(jié),UNICODE 中的字符是用wchar_t來定義的,這中編碼方案則是每個字符都占用兩個字節(jié)。在這種編碼方案下我們又可以一個一個地數(shù)來算出占用了多少字節(jié),計算機(jī)可以用一種統(tǒng)計方式來處理這種字符串了。雖然犧牲了些內(nèi)存,但換取了邏輯的簡單性。
這里我寫了幾個工具函數(shù),可以方便地在各種數(shù)據(jù)類型之間進(jìn)行轉(zhuǎn)換。我認(rèn)為這幾個函數(shù)會對處理字符串提供幫助,所在我就在首頁發(fā)表了。大家有什么好的想法可以回復(fù)我。另我這兩天會封裝MSXML來操作XML,希望大家能給點(diǎn)意見。到時我可以與相關(guān)參與的人員共享這個封裝。
1

/**//**//**///////////////////////////////////////////////////////////////////////////2
// Module: stringutility.h3
// Conversion among wchar_t, char and TCHAR4
//5

/**//**//**///////////////////////////////////////////////////////////////////////////6
#ifndef _STRINGUTILITY_H_7
#define _STRINGUTILITY_H_8

9

/**//**//**///////////////////////////////////////////////////////////////////////////10
// get PSTR by PWSTR11
// This function malloc some memory and you must free it12
inline char* newPSTRFromPWSTRT(PWSTR source)13


{14
char *pCh = NULL;15
int nLength = 0;16
if(!source)17

{18
pCh = new char[1];19
}20
else21

{22
nLength= wcslen(source);23
pCh = new char[2 * nLength + 1];24
WideCharToMultiByte(CP_ACP,25
0,26
source,27
-1,28
pCh,29
nLength * 2,30
NULL,31
NULL);32
}33
pCh[2 * nLength] = '\0';34
return pCh;35
}36

37

/**//**//**///////////////////////////////////////////////////////////////////////////38
// get PWSTR by PSTR39
// This function malloc some memory and you must free it40
inline wchar_t* newPWSTRFromPSTR(PSTR source)41


{42
wchar_t *pCh = NULL;43
int nLength = 0;44
if(!source)45

{46
pCh = new wchar_t[1];47
}48
else49

{50
nLength = strlen(source);51
pCh = new wchar_t[nLength + 1];52
MultiByteToWideChar(CP_ACP,53
0,54
source,55
-1,56
pCh,57
nLength);58
}59
pCh[nLength] = '\0';60
return pCh;61
}62

63

/**//**//**///////////////////////////////////////////////////////////////////////////64
// get PSTR by PTSTR65
// This function malloc some memory and you must free it66

67
inline char* newPSTRFromPTSTR(PTSTR source)68


{69
#ifdef UNICODE70
return newPSTRFromPWSTRT(source);71
#else72
char* pCh;73
int iLength = 0;74
if(!source)75

{76
pCh = new char[1];77
}78
else79

{80
iLength = strlen(source);81
pCh = new char[iLength +1];82
strcpy(pCh, source);83
}84
pCh[iLength] = '\0';85
return pCh;86
#endif87
}88

89

/**//**//**///////////////////////////////////////////////////////////////////////////90
// get PWSTR by PTSTR91
// This function malloc some memory and you must free it92

93
inline wchar_t* newPWSTRFromPTSTR(PTSTR source)94


{95
#ifdef UNICODE96
wchar_t *pCh = NULL;97
int nLength = 0;98
if(!source)99

{100
pCh = new wchar_t[1];101
}102
else103

{104
nLength = wcslen(source);105
pCh = new wchar_t[nLength + 1];106
wcscpy(pCh, source);107
}108
pCh[nLength] = L'\0';109
return pCh;110
#else111
return newPWSTRFromPTSTR(source);112
#endif113
}114

115

116

/**//**//**///////////////////////////////////////////////////////////////////////////117
// get PTSTR by PSTR118
// This function malloc some memory and you must free it119
inline TCHAR* newPTSTRFromPSTR(PSTR source)120


{121
#ifdef UNICODE122
return newPWSTRFromPSTR(source);123
#else124
return newPSTRFromPTSTR(source);125
#endif126
}127

128

/**//**//**///////////////////////////////////////////////////////////////////////////129
// get PTSTR by PWSTR130
// This function malloc some memory and you must free it131
inline TCHAR* newPTSTRFromPWSTR(PWSTR source)132


{133
#ifdef UNICODE134
return newPWSTRFromPTSTR(source);135
#else136
return newPSTRFromPWSTRT(source);137
#endif138
}139
#endif // end of #ifndef _STRINGUTILITY_H_posted on 2008-07-11 23:07 Robertxiao 閱讀(3947) 評論(7) 編輯 收藏 引用 所屬分類: C++

