strex.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #include <StrUtils.hpp>
  12. //////////////////////////////////////////////////////////////////////////////
  13. // More sophisticated construction
  14. CString::CString(const wchar_t * lpch, int nLength)
  15. {
  16. m_Data = UnicodeString(lpch, nLength);
  17. }
  18. /////////////////////////////////////////////////////////////////////////////
  19. // Special conversion constructors
  20. CString::CString(const char * lpsz, int nLength)
  21. {
  22. m_Data = UnicodeString(AnsiString(lpsz, nLength));
  23. }
  24. //////////////////////////////////////////////////////////////////////////////
  25. // Assignment operators
  26. const CString& CString::operator=(wchar_t ch)
  27. {
  28. m_Data = ch;
  29. return *this;
  30. }
  31. //////////////////////////////////////////////////////////////////////////////
  32. // less common string expressions
  33. CString operator+(const CString& string1, wchar_t ch)
  34. {
  35. return CString(string1.m_Data + ch);
  36. }
  37. CString operator+(wchar_t ch, const CString& string)
  38. {
  39. return CString(UnicodeString(ch) + string.m_Data);
  40. }
  41. //////////////////////////////////////////////////////////////////////////////
  42. // Advanced manipulation
  43. int CString::Delete(int nIndex, int nCount /* = 1 */)
  44. {
  45. if (nIndex < 0)
  46. nIndex = 0;
  47. int nNewLength = m_Data.Length();
  48. m_Data.Delete(nIndex + 1, nCount);
  49. return nNewLength;
  50. }
  51. int CString::Replace(wchar_t chOld, wchar_t chNew)
  52. {
  53. int nCount = 0;
  54. // short-circuit the nop case
  55. if (chOld != chNew)
  56. {
  57. // otherwise modify each character that matches in the string
  58. m_Data.Unique();
  59. wchar_t * psz = m_Data.c_str();
  60. wchar_t * pszEnd = psz + m_Data.Length();
  61. while (psz < pszEnd)
  62. {
  63. // replace instances of the specified character only
  64. if (*psz == chOld)
  65. {
  66. *psz = chNew;
  67. nCount++;
  68. }
  69. psz = _wcsinc(psz);
  70. }
  71. }
  72. return nCount;
  73. }
  74. BOOL CString::Replace(const wchar_t * lpszOld, const wchar_t * lpszNew)
  75. {
  76. UnicodeString prev = m_Data;
  77. m_Data = ReplaceStr(m_Data, lpszOld, lpszNew);
  78. return (prev != m_Data);
  79. }
  80. //////////////////////////////////////////////////////////////////////////////
  81. // Very simple sub-string extraction
  82. CString CString::Mid(int nFirst) const
  83. {
  84. return Mid(nFirst, m_Data.Length() - nFirst);
  85. }
  86. CString CString::Mid(int nFirst, int nCount) const
  87. {
  88. // out-of-bounds requests return sensible things
  89. if (nFirst < 0)
  90. nFirst = 0;
  91. if (nCount < 0)
  92. nCount = 0;
  93. if (nFirst + nCount > m_Data.Length())
  94. nCount = m_Data.Length() - nFirst;
  95. if (nFirst > m_Data.Length())
  96. nCount = 0;
  97. ASSERT(nFirst >= 0);
  98. ASSERT(nFirst + nCount <= m_Data.Length());
  99. // optimize case of returning entire string
  100. if (nFirst == 0 && nFirst + nCount == m_Data.Length())
  101. return *this;
  102. return CString(m_Data.SubString(nFirst + 1, nCount));
  103. }
  104. CString CString::Right(int nCount) const
  105. {
  106. if (nCount < 0)
  107. nCount = 0;
  108. if (nCount >= m_Data.Length())
  109. return *this;
  110. return CString(m_Data.SubString(m_Data.Length() - nCount + 1, nCount));
  111. }
  112. CString CString::Left(int nCount) const
  113. {
  114. if (nCount < 0)
  115. nCount = 0;
  116. if (nCount >= m_Data.Length())
  117. return *this;
  118. return CString(m_Data.SubString(1, nCount));
  119. }
  120. //////////////////////////////////////////////////////////////////////////////
  121. // Finding
  122. int CString::ReverseFind(wchar_t ch) const
  123. {
  124. // find last single character
  125. wchar_t * lpsz = wcsrchr(m_Data.c_str(), ch);
  126. // return -1 if not found, distance from beginning otherwise
  127. return (lpsz == NULL) ? -1 : (int)(lpsz - m_Data.c_str());
  128. }
  129. // find a sub-string (like strstr)
  130. int CString::Find(const wchar_t * lpszSub) const
  131. {
  132. return Find(lpszSub, 0);
  133. }
  134. int CString::Find(const wchar_t * lpszSub, int nStart) const
  135. {
  136. int nLength = m_Data.Length();
  137. if (nStart > nLength)
  138. return -1;
  139. // find first matching substring
  140. wchar_t * lpsz = wcsstr(m_Data.c_str() + nStart, lpszSub);
  141. // return -1 for not found, distance from beginning otherwise
  142. return (lpsz == NULL) ? -1 : (int)(lpsz - m_Data.c_str());
  143. }
  144. /////////////////////////////////////////////////////////////////////////////
  145. // CString formatting
  146. void CString::FormatV(const wchar_t * lpszFormat, va_list argList)
  147. {
  148. m_Data.vprintf(lpszFormat, argList);
  149. }
  150. // formatting (using wsprintf style formatting)
  151. void CString::Format(const wchar_t * lpszFormat, ...)
  152. {
  153. va_list argList;
  154. va_start(argList, lpszFormat);
  155. FormatV(lpszFormat, argList);
  156. va_end(argList);
  157. }
  158. void CString::Format(UINT nFormatID, ...)
  159. {
  160. UnicodeString strFormat = LoadStr(nFormatID);
  161. va_list argList;
  162. va_start(argList, nFormatID);
  163. FormatV(strFormat.c_str(), argList);
  164. va_end(argList);
  165. }
  166. void CString::TrimRight(const wchar_t * lpszTargetList)
  167. {
  168. UnicodeString TargetList(lpszTargetList);
  169. while (!m_Data.IsEmpty() && m_Data.IsDelimiter(TargetList, m_Data.Length()))
  170. {
  171. m_Data.SetLength(m_Data.Length() - 1);
  172. }
  173. }
  174. void CString::TrimRight(wchar_t chTarget)
  175. {
  176. TrimRight(UnicodeString(chTarget).c_str());
  177. }
  178. void CString::TrimLeft(const wchar_t * lpszTargets)
  179. {
  180. UnicodeString Targets(lpszTargets);
  181. while (!m_Data.IsEmpty() && m_Data.IsDelimiter(Targets, 1))
  182. {
  183. m_Data.Delete(1, 1);
  184. }
  185. }
  186. void CString::TrimLeft(wchar_t chTarget)
  187. {
  188. TrimLeft(UnicodeString(chTarget).c_str());
  189. }
  190. ///////////////////////////////////////////////////////////////////////////////