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


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_
在上面介紹了許多的字符串,及字符串封裝類。實際上所有的這些類都最終可歸結為C風格字符串,也就是字符數組。目前字符的編碼方案主要有單字節字符(ANSI)編碼,多字節字符(MBCS)編碼,還有就是UNICODE編碼。前兩種字符編碼的字符還都是用char這個數據類型來維護。當是多字節時典型的就是2個字節時,就會用2個char來存儲,一個字節時就會用一個char來存儲。這就是串中的字符占多少個字節得看具體的字符,不能像原來一樣一個一個地數就可以知道會占多少個字節。UNICODE則簡化了這種編碼方案,讓每個字符都占用相同大小的字節,UNICODE 中的字符是用wchar_t來定義的,這中編碼方案則是每個字符都占用兩個字節。在這種編碼方案下我們又可以一個一個地數來算出占用了多少字節,計算機可以用一種統計方式來處理這種字符串了。雖然犧牲了些內存,但換取了邏輯的簡單性。
這里我寫了幾個工具函數,可以方便地在各種數據類型之間進行轉換。我認為這幾個函數會對處理字符串提供幫助,所在我就在首頁發表了。大家有什么好的想法可以回復我。另我這兩天會封裝MSXML來操作XML,希望大家能給點意見。到時我可以與相關參與的人員共享這個封裝。


1


2

3

4

5


6

7

8

9


10

11

12

13



14

15

16

17



18

19

20

21



22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37


38

39

40

41



42

43

44

45



46

47

48

49



50

51

52

53

54

55

56

57

58

59

60

61

62

63


64

65

66

67

68



69

70

71

72

73

74

75



76

77

78

79



80

81

82

83

84

85

86

87

88

89


90

91

92

93

94



95

96

97

98

99



100

101

102

103



104

105

106

107

108

109

110

111

112

113

114

115

116


117

118

119

120



121

122

123

124

125

126

127

128


129

130

131

132



133

134

135

136

137

138

139

posted on 2008-07-11 23:07 Robertxiao 閱讀(3908) 評論(7) 編輯 收藏 引用 所屬分類: C++