Visual Studio 2017 Visual C++ の便利な文字列クラス CStringT の使い方

#はじめに
MFC には CString という独自の文字列クラスがあり、MFC の多くのクラスでよく使われています。しかし、この文字列は MFC DLL に依存しているため、MFC 環境でしか利用できません。

しかし、CString 互換で MFC がなくても利用可能な CStringT というテンプレートベースのクラスが用意されています。これはテンプレートベースなので DLL は不要で、ヘッダーファイルをインクルードするだけで利用できます。

C++ の文字列としては std::string がありますが、Windows 環境に依存するアプリケーションでは使い勝手がよくないので、Windows 環境に適応した CStringT は便利です。

#CStringT を利用するには
CStringT を利用するのは簡単です。ヘッダーファイル "atlstr.h" をインクルードするだけで利用できます。

通常はアプリケーションの "stdafx.h" に次のように "atlstr.h" を追加します。

```C++
// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、または
// 参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル
// を記述します。
//
#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>

// TODO: プログラムに必要な追加ヘッダーをここで参照してください
// #include <atlbase.h>
#include <atlstr.h>
```

#CStringT の機能
基本的には MFC の CString クラスと同じです。さらに言えば、Visual Basic 6 の文字列処理関数と互換のものが多く含まれます。

詳しい情報は下記のリンクを参照してください。

[MSDN: CStringT クラス](https://msdn.microsoft.com/ja-jp/library/5bzxfsea.aspx)

##構築
- CStringT() throw() : CThisSimpleString(StringTraits::GetDefaultManager());
- explicit CStringT(IAtlStringMgr* pStringMgr) throw() : CThisSimpleString(pStringMgr);
- CStringT( const VARIANT& varSrc);
- CStringT(const VARIANT& varSrc, IAtlStringMgr* pStringMgr);
- CStringT(const CStringT& strSrc) : CThisSimpleString(strSrc);
- operator CSimpleStringT<BaseType, !_CSTRING_IMPL_::_MFCDLLTraitsCheck< BaseType, 
 StringTraits>::c_bIsMFCDLLTraits> &()
- template <bool bMFCDLL>CStringT(const CSimpleStringT<BaseType, bMFCDLL>& strSrc) : -
 CThisSimpleString(strSrc);
- template <class SystemString>CStringT(SystemString^ pString) : CThisSimpleString(StringTraits::GetDefaultManager());
- CStringT(const XCHAR* pszSrc) : CThisSimpleString(StringTraits::GetDefaultManager());
- CSTRING_EXPLICIT CStringT(const YCHAR* pszSrc) : CThisSimpleString(StringTraits::GetDefaultManager());
- CStringT(LPCSTR pszSrc, IAtlStringMgr* pStringMgr) : CThisSimpleString(pStringMgr);
- CStringT(LPCWSTR pszSrc, IAtlStringMgr* pStringMgr) : CThisSimpleString(pStringMgr);
- CSTRING_EXPLICIT CStringT(const unsigned char* pszSrc) : CThisSimpleString(StringTraits::GetDefaultManager());
- /*CSTRING_EXPLICIT*/ CStringT(char* pszSrc) : CThisSimpleString(StringTraits::GetDefaultManager());
- CSTRING_EXPLICIT CStringT(unsigned char* pszSrc) : CThisSimpleString(StringTraits::GetDefaultManager());
- CSTRING_EXPLICIT CStringT(wchar_t* pszSrc) : CThisSimpleString(StringTraits::GetDefaultManager());
- CStringT(const unsigned char* pszSrc, IAtlStringMgr* pStringMgr) : CThisSimpleString(pStringMgr);
- CSTRING_EXPLICIT CStringT(char ch, int nLength = 1) : CThisSimpleString(StringTraits::GetDefaultManager());
- CSTRING_EXPLICIT CStringT(wchar_t ch, int nLength = 1) : CThisSimpleString(StringTraits::GetDefaultManager());
- CStringT(const XCHAR* pch, int nLength) : CThisSimpleString(pch, nLength, StringTraits::GetDefaultManager());
- CStringT(const YCHAR* pch, int nLength) : CThisSimpleString(StringTraits::GetDefaultManager());
- CStringT(const XCHAR* pch, int nLength, IAtlStringMgr* pStringMgr) : CThisSimpleString(pch, nLength, pStringMgr);
- CStringT(const YCHAR* pch, int nLength, IAtlStringMgr* pStringMgr) : CThisSimpleString(pStringMgr);

##メソッド一覧
- **BSTR AllocSysString() const;** BSTR 型文字列に CStringT の中身の文字列をコピーする。
- **void AnsiToOem();** ANSI 文字セットを OEM 文字セットに変換する。
- **CStringT::AppendFormat** 既存の CStringT オブジェクトにフォーマット済みデータを追加する。以下の2つのバージョンがある。
 - void __cdecl AppendFormat(PCXSTR pszFormat, [, argument] ...);
 - void __cdecl AppendFormat(UINT nFormatID, [, argument] ...);
- **int Collate(PCXSTR psz) const throw();** _tcscoll (tchar.h で定義されている比較関数でマルチバイト文字とワイド文字を環境に基づき自動判別して比較) に基づいて、psz と CStringT オブジェクトの文字列を比較する。
- **int CollateNoCase(PCXSTR psz) const throw();** CStringT::Collate と同じだが大文字・小文字の区別を行わない。
- **int Compare(PCXSTR psz) const;** psz とこの CStringT オブジェクトの文字列を比較する。(大文字・小文字の区別を行う)
- **int CompareNoCase(PCXSTR psz) const throw();** psz とこの CStringT オブジェクトの文字列を比較する。(大文字・小文字の区別を行わない)
- **int Delete(int iIndex, int nCount = 1);** 位置 iIndex から nCount 数の文字を取り除く。
CStringT::Find 文字または文字列を見つける。次の2つのバージョンがある。
 - int Find(PCXSTR pszSub, int iStart=0) const throw();
 - int Find(XCHAR ch, int iStart=0) const throw();
- **int FindOneOf(PCXSTR pszCharSet) const throw();** pszCharSet に含まれるどれか1つの文字が見つかったら、その場所(インデックス)を返す。見つからない場合は -1 が返される。
- **CStringT::Format** sprintf_s のようにフォーマット化した文字列を、この CStringT オブジェクトの内容とする。次の2つのバージョンがある。
 - void __cdecl Format(UINT nFormatID, [, argument]...);
 - void __cdecl Format(PCXSTR pszFormat, [, argument] ...);
- **CStringT::FormatMessage** メッセージをフォーマットする。次の2つのバージョンがある。
 - void __cdecl FormatMessage(UINT nFormatID, [, argument]...);
 - void __cdecl FormatMessage(PCXSTR pszFormat, [, argument]...);
- **void FormatMessageV(PCXSTR pszFormat, va_list* pArgList);** 引数リストを使って、メッセージをフォーマットする。
- **void FormatV(PCXSTR pszFormat, va_list args);** 引数リストを使って、メッセージをフォーマットする。
- **BOOL GetEnvironmentVariable(PCXSTR pszVar);** 指定された環境変数の値を CStringT オブジェクトの文字列にする。
- **CStringT::Insert** iIndex で指定された位置に文字または文字列を挿入する。次の2つのバージョンがある。
 - int Insert(int iIndex, PCXSTR psz);
 - int Insert(int iIndex, XCHAR ch);
- **CStringT Left(int nCount) const;** 文字列の左側から nCount の文字列を取得する。
- **CStringT::LoadString** nID で指定された Windows 文字列リソースをロードする。次の3つのバージョンがある。
 - BOOL LoadString(HINSTANCE hInstance, UINT nID, WORD wLanguageID);
 - BOOL LoadString(HINSTANCE hInstance, UINT nID);
 - BOOL LoadString(UINT nID);
- **CStringT& MakeLower();** CStringT オブジェクト内の文字列の大文字をすべて小文字にする。
- **CStringT& MakeReverse();** CStringT オブジェクト内の文字列の文字を逆順にする。
- **CStringT& MakeUpper();** CStringT オブジェクト内の文字列の小文字をすべて大文字にする。
- **CStringT::Mid** CStringT オブジェクトの文字列の 位置 iFirst または 先頭から長さ nCount も文字列を取得する。次の2つのバージョンがある。
 - CStringT Mid(int iFirst, int nCount) const;
 - CStringT Mid(int iFirst) const;
- **void OemToAnsi();** OEM 文字から ANSI 文字セットに変換する。
- **int Remove(XCHAR chRemove);** CStringT の文字列から指定した文字をすべて取り除く。
- **CStringT::Replace** CStringT オブジェクト内の文字列に対して、文字列または文字を置き換える。次の2つのバージョンがある。
 - int Replace(PCXSTR pszOld, PCXSTR pszNew);
 - int Replace(XCHAR chOld, XCHAR chNew);
- **int ReverseFind(XCHAR ch) const throw();** CStringT の文字列の最後から文字を検索し、見つかった位置を返す。
- **CStringT Right(int nCount) const;** CStringT の文字列の右側 nCount 文字分を取り出す。
- **BSTR SetSysString(BSTR* pbstr) const;** pbstr で指定された BSTR 文字列をメモリの再割り当てを行って
 CSTringT の文字列としてコピーする。
- **CStringT SpanExcluding(PCXSTR pszCharSet) const;** パラメータに含まれる文字を CStringT の文字列から取り除く。
- **CStringT SpanIncluding(PCXSTR pszCharSet) const;** CStringT の文字列から pszCharSet に含まれる文字からだけなる部分文字列を取り出す。
- **CStringT Tokenize(PCXSTR pszTokens, int& iStart) const;**
CStringT::Trim パラメータで指定した文字または文字列を CStringT 文字列の左右から取り除く。何も指定しない場合は空白を取り除く。次の3つのバージョンがある。
 - CStringT& Trim(XCHAR chTarget);
 - CStringT& Trim(PCXSTR pszTargets);
 - CStringT& Trim();
- **CStringT::TrimLeft** パラメータで指定した文字または文字列を CStringT 文字列の左から取り除く。何も指定しない場合は空白を取り除く。次の3つのバージョンがある。
 - CStringT& TrimLeft(XCHAR chTarget);
 - CStringT& TrimLeft(PCXSTR pszTargets);
 - CStringT& TrimLeft();
- **CStringT::TrimRight** パラメータで指定した文字または文字列を CStringT 文字列の右から取り除く。何も指定しない場合は空白を取り除く。次の3つのバージョンがある。
 - CStringT& TrimRight(XCHAR chTarget);
 - CStringT& TrimRight(PCXSTR pszTargets);
 - CStringT& TrimRight();

##演算子一覧
- **CStringT::operator +** 文字列を結合する。次のバージョンがある。
 - friend CStringT operator+(const CStringT& str1, const CStringT& str2);
 - friend CStringT operator+(const CStringT& str1, PCXSTR psz2);
 - friend CStringT operator+(PCXSTR psz1, const CStringT& str2,);
 - friend CStringT operator+(char ch1, const CStringT& str2,);
 - friend CStringT operator+(const CStringT& str1, char ch2);
 - friend CStringT operator+(const CStringT& str1, wchar_t ch2);
 - friend CStringT operator+(wchar_t ch1, const CStringT& str2,);
- **CStringT::operator +=** CStringT の文字列の最後に他の文字列を結合する。次のバージョンがある。
 - CStringT& operator+=(const CThisSimpleString& str);
 - template<bool bMFCDLL> CStringT& operator+=(const const CSimpleStringT<BaseType, bMFCDLL>& str);
 - template<int t_nSize> CStringT& operator+=(const CStaticString<XCHAR, t_nSize>& strSrc);
 - CStringT& operator+=(PCXSTR pszSrc);
 - CStringT& operator+=(PCYSTR pszSrc);
 - CStringT& operator+=(char ch);
 - CStringT& operator+=(unsigned char ch);
 - CStringT& operator+=(wchar_t ch);
 - CStringT& operator+=(const VARIANT& var);
- **CStringT::operator ==**　等号演算子。以下のバージョンがある。
 - friend bool operator==(const CStringT& str1, const CStringT& str2) throw();
 - friend bool operator==(const CStringT& str1, PCXSTR psz2) throw();
 - friend bool operator==(const CStringT& str1, PCYSTR psz2) throw();
 - friend bool operator==(const CStringT& str1, XCHAR ch2) throw();
 - friend bool operator==(PCXSTR psz1, const CStringT& str2) throw();
 - friend bool operator==(PCYSTR psz1, const CStringT& str2,) throw();
 - friend bool operator==(XCHAR ch1, const CStringT& str2,) throw();
- **CStringT::operator !=**　不等号演算子。以下のバージョンがある。
 - friend bool operator!=(const CStringT& str1, const CStringT& str2) throw();
 - friend bool operator!=(const CStringT& str1, PCXSTR psz2) throw();
 - friend bool operator!=(const CStringT& str1, PCYSTR psz2) throw();
 - friend bool operator!=(const CStringT& str1, XCHAR ch2) throw();
 - friend bool operator!=(PCXSTR psz1, const CStringT& str2) throw();
 - friend bool operator!=(PCYSTR psz1, const CStringT& str2,) throw();
 - friend bool operator!=(XCHAR ch1, const CStringT& str2,) throw();
- **CStringT::operator <**　小なり演算子。以下のバージョンがある。
 - friend bool operator < (const CStringT& str1, const CStringT& str2) throw();
 - friend bool operator < (const CStringT& str1, PCXSTR psz2) throw();
 - friend bool operator < (PCXSTR psz1, const CStringT& str2) throw();
- **CStringT::operator >**　大なり演算子。以下のバージョンがある。
 - friend bool operator > (const CStringT& str1, const CStringT& str2) throw();
 - friend bool operator > (const CStringT& str1, PCXSTR psz2) throw();
 - friend bool operator > (PCXSTR psz1, const CStringT& str2) throw();
- **CStringT::operator <=**　等しいか小さい判別演算子。以下のバージョンがある。
 - friend bool operator <= (const CStringT& str1, const CStringT& str2) throw();
 - friend bool operator <= (const CStringT& str1, PCXSTR psz2) throw();
 - friend bool operator <= (PCXSTR psz1, const CStringT& str2) throw();
- **CStringT::operator >=**　等しいか大きい判別演算子。以下のバージョンがある。
 - friend bool operator >= (const CStringT& str1, const CStringT& str2) throw();
 - friend bool operator >= (const CStringT& str1, PCXSTR psz2) throw();
 - friend bool operator >= (PCXSTR psz1, const CStringT& str2) throw();

#サンプル
このサンプルは、通常のコンソールアプリケーションです。ヘッダーファイル "stdafx.h" は前述の通りです。

```C++
// TestCStringT.cpp : アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

//
//  CStringT クラスのテスト
//  =======================
int main()
{
	// 普通に宣言する場合
	CStringT<TCHAR, StrTraitATL<TCHAR> > s1 = _T("ABCDEF");
	s1.Append(_T("GHIJKL"));
	wprintf_s(L"%s\n", (LPCWSTR)s1);

	// MFC ベースのアプリ内で使用可能 (CString は CStringT の別名になっている)
	CString s2 = _T("abcdef");
	s2.Append(_T("GHIJKL"));
	wprintf_s(L"%s\n", (LPCWSTR)s2);

	// ATL ベースのアプリ内のみ使用可能 (CAtlString は CStringT の別名になっている)
	CAtlString s3 = _T("ABCDEF");
	s3.Append(_T("ghijkl"));
	wprintf_s(L"%s\n", (LPCWSTR)s3);

	// C の関数で文字列のように使用できる。
	WCHAR buff[80];
	StrCpyW(buff, s3);
	wprintf_s(L"%s\n", buff);

	// BSTR といっしょに使用
	BSTR bstr = s1.AllocSysString();
	wprintf_s(L"%s\n", bstr);
	s2 = bstr;
	wprintf_s(L"%s\n", s2);

	::SysFreeString(bstr);
	getchar();
    return 0;
}
```

-