曾經有一篇關於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
12inline 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
40inline 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
67inline 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
93inline 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}
114115116/**//**//**///////////////////////////////////////////////////////////////////////////
117// get PTSTR by PSTR
118// This function malloc some memory and you must free it
119inline TCHAR* newPTSTRFromPSTR(PSTR source)
120{
121#ifdef UNICODE
122 return newPWSTRFromPSTR(source);
123#else
124 return newPSTRFromPTSTR(source);
125#endif
126}
127128/**//**//**///////////////////////////////////////////////////////////////////////////
129// get PTSTR by PWSTR
130// This function malloc some memory and you must free it
131inline 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_
<script type="text/javascript">
//
Sys.WebForms.PageRequestManager._initialize('AjaxHolder$scriptmanager1', document.getElementById('Form1'));
Sys.WebForms.PageRequestManager.getInstance()._updateControls(['tAjaxHolder$UpdatePanel1'], [], [], 90);
//
</script>
# re: C++ 字符串操作初析[未登錄]
2008-07-11 23:46
評論
WideCharToMultiByte MultiByteToWideChar 包裝了這兩個API,挺好,
re: C++ 字符串操作初析 2008-07-12 07:31
樓主所言極是,確實在字符串處理方面有點傷神,有時一個項目用到了幾個第三方庫,常常由於函數接口的字符串類型不一致,需進行調整擴展。
re: C++ 字符串操作初析 2008-07-12 12:39
我現在就用wstring和string兩種東西。。。其他的基本不用了。 那點效率我也不大稀罕的。 至於XML,何必用MSXML,普通的DOM用TinyXML就很好了。 如果你要支持DTD或者XML Schema這樣的除外。
re: C++ 字符串操作初析 2008-07-12 15:11
推薦開源c++ 庫,,裏面對std::string 進行了一些擴展,個人覺得不錯