
Бывалый

Профиль
Группа: Участник
Сообщений: 178
Регистрация: 3.10.2003
Где: Киев
Репутация: нет Всего: нет
|
Я пользуюсь VS6. Когда нужно CString без MFC, то я пользуюсь библиотекой WTL 7. Там этот класс реализован в <atlmisc.h>. Одно плохо - WTL 7.0 нужно отдельно выкачивать. Её нет ни в самой студии, ни в SDK. Ну а с 7ой студии реализация CString есть в <atlstr.h> А очень давно, когда у меня небыло доступа в инет (чтобы спросить), нужно было использовать на чистом API мои же модули, где из всего MFC использовался только класс CString. Можно было переписать все модули под std::string, но я поступил по-другому - сделал обёртку над строкой из STD, которая предоставляла более привычный мне интерфейс класса CString. Код | //////////////////////////////////////////////////////////////////////////////// // File name: CStringKS.h // // Description: Класс для работы со строками. // Реализует почти весь интерфейс CString из MFC. // Для чего это было написано? Когда не нужно пользоваться MFC, но нужен // привычный CString и нет ни библиотеки ATL (из 7ой студии - файл <atlstr.h>), // ни библиотеки WTL 7.0 (файл <atlmisc.h>), где этот класс и реализован. // Класс CStringKS - это обёртка std::string, которая предоставляет // пользователю привычный интерфейс CString. // При использовании MFC, CString и CStringKS - это 2 разных класса. // А при использовании только Win32 API - это один и тот же класс CStringKS. // // Особенности: // 1. Если в MFC можно было так писать: // CString str1(_T("qwerty")); // CString str2; // str2.Format(_T("str1 = %s"), str1); // То при использовании CStringKS надо писать так: // CStringKS str1(_T("qwerty")); // CStringKS str2; // str2.Format(_T("str1 = %s"), (LPCTSTR)str1); // // 2. Нереализованные методы из MFC: // friend CArchive& operator<<(CArchive& ar, const CString& string); // friend CArchive& operator>>(CArchive& ar, CString& string); // LPTSTR LockBuffer(); // void UnlockBuffer(); // ////////////////////////////////////////////////////////////////////////////////
#ifndef __FILE__CSTRINGKS__ #define __FILE__CSTRINGKS__
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include <TChar.H> #include <ComDef.h> #pragma warning(disable:4786) // identifier was truncated to '255' characters in the debug information #include <string> #include <crtdbg.h> #include <ATLConv.H>
class CStringKS { private: #ifdef UNICODE typedef std::wstring tstring; #else typedef std:: string tstring; #endif // UNICODE tstring m_str; public:
// Constructors
// constructs empty CStringKS CStringKS() {} // copy constructor CStringKS(const CStringKS& stringSrc) : m_str((LPCTSTR)stringSrc) {} // from a single character CStringKS(TCHAR ch, int nRepeat = 1) : m_str(tstring(nRepeat, ch)) {} // from an ANSI string (converts to TCHAR) CStringKS(LPCSTR lpsz) {if (lpsz!=NULL) {USES_CONVERSION; m_str = A2CT(lpsz);}} // from a UNICODE string (converts to TCHAR) CStringKS(LPCWSTR lpsz) {if (lpsz!=NULL) {USES_CONVERSION; m_str = W2CT(lpsz);}} // subset of characters from an ANSI string (converts to TCHAR) CStringKS(LPCSTR lpch, int nLength) : m_str((LPCTSTR)(CStringKS(lpch).Left(nLength))) {} // subset of characters from a UNICODE string (converts to TCHAR) CStringKS(LPCWSTR lpch, int nLength) : m_str((LPCTSTR)(CStringKS(lpch).Left(nLength))) {} // from unsigned characters CStringKS(const unsigned char* psz) {this->operator=(psz);}
// Attributes & Operations
// get data length int GetLength() const {return m_str.length();} // TRUE if zero length BOOL IsEmpty() const {return m_str.empty();} // clear contents to empty void Empty() {m_str.erase();}
// return single character at zero-based index TCHAR GetAt(int nIndex) const {return m_str[nIndex];} // return single character at zero-based index TCHAR operator[](int nIndex) const {return m_str[nIndex];} // set a single character at zero-based index void SetAt(int nIndex, TCHAR ch) {m_str[nIndex] = ch;} // return pointer to const string operator LPCTSTR() const {return m_str.c_str();}
// overloaded assignment
// ref-counted copy from another CStringKS const CStringKS& operator=(const CStringKS& stringSrc) { if (&stringSrc != this) {m_str = (LPCTSTR)stringSrc;} return *this;} // set string content to single character const CStringKS& operator=(TCHAR ch) {m_str = ch; return *this;} #ifdef _UNICODE const CStringKS& operator=(char ch) {TCHAR tCh = ch; m_str = tCh; return *this;} #endif // copy string content from ANSI string (converts to TCHAR) const CStringKS& operator=(LPCSTR lpsz) {m_str = (LPCTSTR)CStringKS(lpsz); return *this;} // copy string content from UNICODE string (converts to TCHAR) const CStringKS& operator=(LPCWSTR lpsz) {m_str = (LPCTSTR)CStringKS(lpsz); return *this;} // copy string content from unsigned chars const CStringKS& operator=(const unsigned char* psz) {USES_CONVERSION; m_str = A2CT((const char*)psz); return *this;}
// string concatenation
// concatenate from another CStringKS const CStringKS& operator+=(const CStringKS& string) {m_str += (LPCTSTR)string; return *this;}
// concatenate a single character const CStringKS& operator+=(TCHAR ch) {m_str += ch; return *this;} #ifdef _UNICODE // concatenate an ANSI character after converting it to TCHAR const CStringKS& operator+=(char ch) {TCHAR tCh = ch; m_str += tCh; return *this;} #endif // concatenate a UNICODE character after converting it to TCHAR const CStringKS& operator+=(LPCTSTR lpsz) {m_str += lpsz; return *this;}
friend CStringKS operator+(const CStringKS& string1, const CStringKS& string2) {CStringKS str(string1); return (str += string2);} friend CStringKS operator+(const CStringKS& string, TCHAR ch) {CStringKS str(string); return (str += ch );} friend CStringKS operator+(TCHAR ch, const CStringKS& string) {CStringKS str(ch ); return (str += string);} #ifdef _UNICODE friend CStringKS operator+(const CStringKS& string, char ch) {CStringKS str(string); TCHAR tCh = ch; return (str += tCh);} friend CStringKS operator+(char ch, const CStringKS& string) {TCHAR tCh = ch; CStringKS str(tCh); return (str += string);} #endif friend CStringKS operator+(const CStringKS& string, LPCTSTR lpsz) {CStringKS str(string); return (str += lpsz );} friend CStringKS operator+(LPCTSTR lpsz, const CStringKS& string) {CStringKS str(lpsz ); return (str += string);}
// string comparison
// straight character comparison int Compare (LPCTSTR lpsz) const {return _tcscmp (this->operator LPCTSTR(), lpsz);} // compare ignoring case int CompareNoCase(LPCTSTR lpsz) const {return _tcsicmp (this->operator LPCTSTR(), lpsz);} // NLS aware comparison, case sensitive int Collate (LPCTSTR lpsz) const {return _tcscoll (this->operator LPCTSTR(), lpsz);} // NLS aware comparison, case insensitive int CollateNoCase(LPCTSTR lpsz) const {return _tcsicoll(this->operator LPCTSTR(), lpsz);}
// simple sub-string extraction
// return nCount characters starting at zero-based nFirst CStringKS Mid(int nFirst, int nCount) const {return Mid(nFirst).Left(nCount);} // return all characters starting at zero-based nFirst CStringKS Mid(int nFirst) const {return CStringKS(this->operator LPCTSTR()+max(0,nFirst));} // return first nCount characters in string CStringKS Left(int nCount) const {CStringKS str; for (int i=0; i<nCount; i++) str += GetAt(i); return str;} // return nCount characters from end of string CStringKS Right(int nCount) const {return Mid(GetLength()-max(0,nCount));}
// characters from beginning that are also in passed string CStringKS SpanIncluding(LPCTSTR lpszCharSet) const {CStringKS str; for (int i=0; i<GetLength(); i++) if(_tcschr(lpszCharSet, GetAt(i)) != NULL) str += GetAt(i); else break; return str;} // characters from beginning that are not also in passed string CStringKS SpanExcluding(LPCTSTR lpszCharSet) const {CStringKS str; for (int i=0; i<GetLength(); i++) if(_tcschr(lpszCharSet, GetAt(i)) == NULL) str += GetAt(i); else break; return str;}
// upper/lower/reverse conversion
// NLS aware conversion to uppercase void MakeUpper() { //TCHAR *szStr = new TCHAR[1+GetLength()]; //_tcscpy(szStr, this->operator LPCTSTR()); ::CharUpper((LPTSTR)this->operator LPCTSTR());//::CharUpper(szStr); //m_str = szStr; //delete szStr; } // NLS aware conversion to lowercase void MakeLower() { //TCHAR *szStr = new TCHAR[1+GetLength()]; //_tcscpy(szStr, this->operator LPCTSTR()); ::CharLower((LPTSTR)this->operator LPCTSTR());//::CharLower(szStr); //m_str = szStr; //delete szStr; } // reverse string right-to-left void MakeReverse() { int len = GetLength(); for (int i=0; i<(len>>1); i++) { TCHAR ch = GetAt(i); SetAt(i, GetAt(len-i-1)); SetAt(len-i-1, ch); } }
// trimming whitespace (either side)
// remove whitespace starting from right edge void TrimRight() {TrimRight(_T(' '));} // remove whitespace starting from left side void TrimLeft () {TrimLeft (_T(' '));}
// trimming anything (either side)
// remove continuous occurrences of chTarget starting from right void TrimRight(TCHAR chTarget) { for (int i=GetLength()-1; i>=0; i--) { if (GetAt(i) != chTarget) { operator =(Left(i+1)); break; } } } // remove continuous occcurrences of characters in passed string, // starting from right void TrimRight(LPCTSTR lpszTargets) { int pos = -1; CStringKS strTargets(lpszTargets); for (int i=GetLength()-1; i>=0; i--) { if (strTargets.Find(GetAt(i)) != -1) { pos = i; } else { break; } } if (pos >= 0) { operator =(Left(pos)); } } // remove continuous occurrences of chTarget starting from left void TrimLeft(TCHAR chTarget) { for (int i=0; i<GetLength(); i++) { if (GetAt(i) != chTarget) { operator =(Mid(i)); break; } } } // remove continuous occcurrences of characters in // passed string, starting from left void TrimLeft(LPCTSTR lpszTargets) { int pos = -1; CStringKS strTargets(lpszTargets); for (int i=0; i<GetLength(); i++) { if (strTargets.Find(GetAt(i)) != -1) { pos = i; } else { break; } } if (pos >= 0) { operator =(Mid(i)); } }
// advanced manipulation
// replace occurrences of chOld with chNew int Replace(TCHAR chOld, TCHAR chNew) { int count = 0; for (int i=0; i<GetLength(); i++) { if (GetAt(i) == chOld) { SetAt(i, chNew); count++; } } return count; }
// replace occurrences of substring lpszOld with lpszNew; // empty lpszNew removes instances of lpszOld int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew) { int count = 0; if (lpszOld) { int pos = 0; size_t len = _tcslen(lpszOld); do { pos = Find(lpszOld, pos); if (pos == -1) break; count++; if (lpszNew) { m_str.replace(pos, len, lpszNew); } else { m_str.erase(pos, len); } } while (true); } return count; } // remove occurrences of chRemove int Remove(TCHAR chRemove) { int count = 0; int i=0; while (i<GetLength()) { if (GetAt(i) == chRemove) { Delete(i); count++; } else { i++; } } return count; } // insert character at zero-based index; concatenates // if index is past end of string int Insert(int nIndex, TCHAR ch) { m_str.insert(max(0, min(nIndex, GetLength())), 1, ch); return GetLength(); } // insert substring at zero-based index; concatenates // if index is past end of string int Insert(int nIndex, LPCTSTR pstr) { if (pstr) { m_str.insert(max(0, min(nIndex, GetLength())), pstr); } return GetLength(); } // delete nCount characters starting at zero-based index int Delete(int nIndex, int nCount = 1) { const int iRes = GetLength(); if (nCount > 0) { nIndex = max(0, nIndex); nCount = min(nCount, GetLength()-nIndex); m_str.erase(nIndex, nCount); } return iRes; }
// searching
// find character starting at left, -1 if not found int Find(TCHAR ch) const {return m_str.find(ch);} // find character starting at right int ReverseFind(TCHAR ch) const {return m_str.rfind(ch);} // find character starting at zero-based index and going right int Find(TCHAR ch, int nStart) const {return m_str.find(ch, nStart);} // find first instance of any character in passed string int FindOneOf(LPCTSTR lpszCharSet) const {return m_str.find_first_of(lpszCharSet);} // find first instance of substring int Find(LPCTSTR lpszSub) const {return m_str.find(lpszSub);} // find first instance of substring starting at zero-based index int Find(LPCTSTR lpszSub, int nStart) const {return m_str.find(lpszSub, nStart);}
// simple formatting
// printf-like formatting using passed string void Format(LPCTSTR lpszFormat, ...) { va_list arglist; va_start(arglist, lpszFormat); FormatV(lpszFormat, arglist); va_end(arglist); } // printf-like formatting using referenced string resource void Format(UINT nFormatID, ...) { va_list arglist; va_start(arglist, nFormatID); CStringKS strLoad; BOOL bRes = strLoad.LoadString(nFormatID); if (bRes) { FormatV(strLoad, arglist); } else { Empty(); } va_end(arglist); } // printf-like formatting using variable arguments parameter void FormatV(LPCTSTR lpszFormat, va_list argList) { size_t sizeBuff = 512; TCHAR *szFormat = NULL; int write = -1; do { sizeBuff = sizeBuff<<1; szFormat = new TCHAR[sizeBuff]; if (szFormat) { szFormat[0] = 0; write = _vsntprintf(szFormat, sizeBuff-1, lpszFormat, argList); if (write >= 0) { m_str = szFormat; } delete [] szFormat; } else { break; } } while (write < 0); }
// formatting for localization (uses FormatMessage API)
// format using FormatMessage API on passed string void FormatMessage(LPCTSTR lpszFormat, ...) { va_list argList; va_start(argList, lpszFormat); LPTSTR lpszTemp; if ((::FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0) && (lpszTemp == NULL)) { *this = lpszTemp; LocalFree(lpszTemp); } va_end(argList); } // format using FormatMessage API on referenced string resource void FormatMessage(UINT nFormatID, ...) { CStringKS strFormat; if (strFormat.LoadString(nFormatID)) { va_list argList; va_start(argList, nFormatID); LPTSTR lpszTemp; if ((::FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, strFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList) == 0) && (lpszTemp == NULL)) { *this = lpszTemp; LocalFree(lpszTemp); } va_end(argList); } }
// input and output //friend CArchive& operator<<(CArchive& ar, const CStringKS& string); //friend CArchive& operator>>(CArchive& ar, CStringKS& string);
// load from string resource BOOL LoadString(UINT nID) { size_t sizeBuff = 512; bool bRepeat; int iRes = 0; TCHAR *szFormat = NULL; do { sizeBuff = sizeBuff<<1; szFormat = new TCHAR[sizeBuff]; if (szFormat) { szFormat[0] = 0; iRes = ::LoadString(::GetModuleHandle(NULL), nID, szFormat, sizeBuff); bRepeat = (iRes+1 >= sizeBuff); if (!bRepeat) { m_str = szFormat; } delete [] szFormat; } else { break; } } while (bRepeat); return (iRes > 0); }
#ifndef _UNICODE // ANSI <-> OEM support (convert string in place)
// convert string from ANSI to OEM in-place void AnsiToOem() {::CharToOem((LPCTSTR)this->operator LPCTSTR(), (LPSTR) this->operator LPCTSTR());} // convert string from OEM to ANSI in-place void OemToAnsi() {::OemToChar((LPCSTR) this->operator LPCTSTR(), (LPTSTR)this->operator LPCTSTR());} #endif
#ifndef _AFX_NO_BSTR_SUPPORT // OLE BSTR support (use for OLE automation)
// return a BSTR initialized with this CStringKS's data BSTR AllocSysString() const {USES_CONVERSION; return SysAllocString(T2COLE(m_str.c_str()));} // reallocates the passed BSTR, copies content of this CStringKS to it BSTR SetSysString(BSTR* pbstr) const {BSTR szRes = AllocSysString(); if (pbstr) {::SysFreeString(*pbstr); *pbstr=szRes;} return szRes;} #endif
// Access to string implementation buffer as "C" character array
// get pointer to modifiable buffer at least as long as nMinBufLength LPTSTR GetBuffer(int nMinBufLength) { if (GetLength() < nMinBufLength) { m_str.resize(nMinBufLength); } return (LPTSTR)this->operator LPCTSTR(); } // release buffer, setting length to nNewLength (or to first nul if -1) void ReleaseBuffer(int nNewLength = -1) { if (nNewLength != -1) { nNewLength = max(0, nNewLength); m_str.resize(nNewLength); } FreeExtra(); } // get pointer to modifiable buffer exactly as long as nNewLength LPTSTR GetBufferSetLength(int nNewLength) { return GetBuffer(nNewLength);} // release memory allocated to but unused by string void FreeExtra() { int pos = Find(_T('\0')); if (pos != -1) { m_str.resize(pos); } }
// Use LockBuffer/UnlockBuffer to turn refcounting off
// turn refcounting back on LPTSTR LockBuffer(); // turn refcounting off void UnlockBuffer();
// Implementation public: ~CStringKS() {} int GetAllocLength() const {return GetLength();}; };
// Compare helpers __forceinline bool operator==(const CStringKS& s1, const CStringKS& s2) { return (s1.Compare(s2) == 0); } __forceinline bool operator==(const CStringKS& s1, LPCTSTR s2) { return (s1.Compare(s2) == 0); } __forceinline bool operator==(LPCTSTR s1, const CStringKS& s2) { return (s2.Compare(s1) == 0); } __forceinline bool operator!=(const CStringKS& s1, const CStringKS& s2) { return (s1.Compare(s2) != 0); } __forceinline bool operator!=(const CStringKS& s1, LPCTSTR s2) { return (s1.Compare(s2) != 0); } __forceinline bool operator!=(LPCTSTR s1, const CStringKS& s2) { return (s2.Compare(s1) != 0); } __forceinline bool operator<(const CStringKS& s1, const CStringKS& s2) { return (s1.Compare(s2) < 0); } __forceinline bool operator<(const CStringKS& s1, LPCTSTR s2) { return (s1.Compare(s2) < 0); } __forceinline bool operator<(LPCTSTR s1, const CStringKS& s2) { return (s2.Compare(s1) > 0); } __forceinline bool operator>(const CStringKS& s1, const CStringKS& s2) { return (s1.Compare(s2) > 0); } __forceinline bool operator>(const CStringKS& s1, LPCTSTR s2) { return (s1.Compare(s2) > 0); } __forceinline bool operator>(LPCTSTR s1, const CStringKS& s2) { return (s2.Compare(s1) < 0); } __forceinline bool operator<=(const CStringKS& s1, const CStringKS& s2) { return (s1.Compare(s2) <= 0); } __forceinline bool operator<=(const CStringKS& s1, LPCTSTR s2) { return (s1.Compare(s2) <= 0); } __forceinline bool operator<=(LPCTSTR s1, const CStringKS& s2) { return (s2.Compare(s1) >= 0); } __forceinline bool operator>=(const CStringKS& s1, const CStringKS& s2) { return (s1.Compare(s2) >= 0); } __forceinline bool operator>=(const CStringKS& s1, LPCTSTR s2) { return (s1.Compare(s2) >= 0); } __forceinline bool operator>=(LPCTSTR s1, const CStringKS& s2) { return (s2.Compare(s1) <= 0); }
#ifndef __AFX_H__ typedef CStringKS CString; #endif
#endif // __FILE__CSTRINGKS__
|
|