まだ執筆中なんですが、
C言語のところはそこそこ書けてるので、
退屈しのぎにどうぞ。↓
#pragma once
#ifndef _STL_STRINGW_H_
#define _STL_STRINGW_H_
#include <vector>
#include <string>
using namespace std;
namespace STL
{
// ———————————————————————
// NotFound定数 ( 検索した際に、条件に一致する位置が見つからなかった時に返る値。)
#define NotFound 4294967295 // std::wstring::npos
// ———————————————————————
// ワイド文字列クラスの定義 ( std::wstringのラッパー )
//・UTF-16LE ( Unicode文字列。1文字の文字コードは、2byte固定 )
class /*_EXPORT */ CStringW
{
// ————————————————-
// データメンバ
protected:
std::wstring text; // ワイド文字列の本体。
// マルチバイトを使う場合は、ここを std::string にする。
public:
// —————————————————–<OK><テスト済み>
// イテレーター
typedef std::wstring::iterator Iterator; // 通常のイテレーター (ランダムアクセス)
typedef std::wstring::reverse_iterator RevIterator; // 逆順イテレーター (ランダムアクセス)
// ————————————————-
// コンストラクタ
CStringW(void) : text()
{
}
// ————————————————-
// コンストラクタ
CStringW( CStringW& text_ ) : text( text_.GetString() )
{
}
// ————————————————-
// コンストラクタ
CStringW( const std::wstring& text_ ) : text( text_ )
{
}
// ————————————————-<OK><テスト済み>
// コンストラクタ
CStringW( const WCHAR* p_text_ ) : text( p_text_ )
{
}
// ————————————————-<OK><テスト済み>
// デストラクタ
~CStringW(void)
{
}
// ————————————————-<OK><テスト済み>
//【ワイド文字列】を返す。
inline std::wstring& GetString(void)
{
return text;
}
// ————————————————-<OK><テスト済み>
//【ワイド文字列】を変更する。
inline void SetString( std::wstring& text_ )
{
text = text_;
}
// ————————————————-<OK><テスト済み>
//【指定indexの1文字】を返す。 ( at() )
inline WCHAR GetChar( const size_t index_ )
{
return text.at( index_ );
}
// ————————————————-<OK><テスト済み>
//【ポインタ】を返す。 ( c_str() )
// ※返される文字列は、終端に必ずNULL文字が付加されている。
// ・文字数0の場合、p_result[0]は、NULL文字。
// ・p_result[ length ] は、NULL文字。
inline const WCHAR* GetPtr(void)
{
return text.c_str(); // data() と同じ。
}
// —————————————————–<OK><テスト済み>
//【指定indexのイテレータ】を返す。
// ※戻り値のイテレータを、参照にしていないのには理由がある。
// このクラスがローカル変数として宣言された場合、
// スタック領域のアドレスを返してしまうためコケるからである。
inline Iterator GetItr( const size_t index_ )
{
return ( text.begin() + index_ );
}
// ————————————————-
//【文字数】を返す。 ( length() or size() )
// ※終端のNULL文字を含まない。
inline size_t GetLength()
{
return text.length();
}
// ————————————————-
//【最大文字数】を返す。 ( max_size() )
inline size_t GetMaxLength()
{
return text.max_size();
}
// ————————————————-<OK><テスト済み>
//【文字列】を初期化する。 ( assign() )
// ※ std::wstring::value_type は、wchar_t 。
// STL::CStringW text1;
// text1.Init( L”あいうえお”, 3 ); // text1 は、”あいう” で初期化される。
inline std::wstring& Init( const WCHAR* p_text_ )
{
return text.assign( p_text_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を初期化する。 ( append() )
// STL::CStringW text1;
// text1.Init( L”あいうえお”, 3 ); // text1 は、”あいう” で初期化される。
inline std::wstring& Init( const WCHAR* p_text_ , const size_t length_ )
{
return text.assign( p_text_, length_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】で初期化する。 ( append() )
// STL::CStringW text1;
// std::wstring text2( L”かきくけこ” );
// text1.InitByString( text2 ); // text1 は、”かきくけこ” で初期化される。
inline void InitByString( const std::wstring& text_ )
{
text.assign( text_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】で初期化する。 ( append() )
// STL::CStringW text1;
// std::wstring text2( L”かきくけこ” );
// text1.InitByString( text2, 1, 2 ); // text1 は、”きく” で初期化される。
inline std::wstring& InitByString(
const std::wstring& text_, // この文字列中の、部分文字列で初期化される。
const size_t start_index_, // 部分文字列の開始位置。
const size_t length_ // 部分文字列の文字数。
)
{
return text.assign( text_, start_index_, length_ );
}
// ————————————————-<OK><テスト済み>
//【指定した文字】で初期化する。 ( append() )
// STL::CStringW text1;
// text1.InitByChar( L’あ’, 3 ); // text1 は、”あああ” で初期化される。
inline std::wstring& InitByChar( const WCHAR char_, const size_t count_ )
{
return text.assign( count_, char_ );
}
// ————————————————-<OK><テスト済み>
//【指定範囲の文字列】で初期化する。( ポインタ版 ) ( append() )
// STL::CStringW text1;
// WCHAR src[] = L”かきくけこ”;
// text1.InitByRange( src + 1, src + 3 ); // text1 は、”きく” で初期化される。
inline std::wstring& InitByRange( const WCHAR* p_src_start_, const WCHAR* p_src_end_ )
{
return text.assign( p_src_start_, p_src_end_ );
}
// ————————————————-<OK><テスト済み>
//【指定範囲の文字列】で初期化する。( イテレータ版 ) ( append() )
// STL::CStringW text1;
// std::wstring src( L”かきくけこ”);
// std::wstring::iterator itr = src.begin();
// text1.InitByRange( itr + 1, itr + 3 ); // text1 は、”きく” で初期化される。
inline std::wstring& InitByRange( const Iterator src_start_itr_, const Iterator src_end_itr_ )
{
return text.assign( src_start_itr_, src_end_itr_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列】と比較する。 ( compare() )
// ※この比較では、大文字・小文字は区別される。
// ( ( L”Uma” == L”uma” ) は false )
inline bool Compare( const std::wstring& text_ )
{
return ( text.compare( text_ ) == 0 );
}
// ————————————————-<OK><テスト済み>
//【指定範囲】と【指定文字列】を比較する。( compare() )
// 引数1,2で指定された範囲の部分文字列と、指定された文字列を比較する。
inline bool Compare(
const size_t index_, // 比較する部分のオフセット。 ( この文字列の )
const size_t length_, // 比較する部分の文字数。( この文字列の )
const std::wstring& text_ // 比較する文字列。
)
{
return ( text.compare( index_, length_, text_ ) == 0 );
}
// ————————————————-<OK><テスト済み>
//【指定範囲】と【指定文字列の指定範囲】を比較する。( compare() )
inline bool Compare(
const size_t index_, // 比較する部分のオフセット。 ( この文字列の )
const size_t length_, // 比較する部分の文字数。( この文字列の )
const std::wstring& text_, // 比較する文字列。
const size_t text_offset_, // 比較する部分のオフセット。 ( 指定文字列の )
const size_t text_length_ // 比較する部分の文字数。( 指定文字列の )
)
{
return ( text.compare( index_, length_, text_, text_offset_, text_length_ ) == 0 );
}
// ————————————————-<OK><テスト済み>
//【指定文字列】と比較する。 ( compare() )
inline bool Compare( const WCHAR* p_text_ )
{
return ( text.compare( p_text_ ) == 0 );
}
// ————————————————-<OK><テスト済み>
//【指定範囲】と【指定文字列】を比較する。( compare() )
inline bool Compare(
const size_t index_, // 比較する部分のオフセット。 ( この文字列の )
const size_t length_, // 比較する部分の文字数。( この文字列の )
const WCHAR* p_text_ // 比較する文字列。
)
{
return ( text.compare( index_, length_, p_text_ ) == 0 );
}
// ————————————————-<OK><テスト済み>
//【指定範囲】と【指定文字列の指定範囲】を比較する。( compare() )
inline bool Compare(
const size_t index_, // 比較する部分のオフセット。 ( この文字列の )
const size_t length_, // 比較する部分の文字数。( この文字列の )
const WCHAR* p_text_, // 比較する文字列。
const size_t text_length_ // 比較する部分の文字数。( 指定文字列の )
)
{
return ( text.compare( index_, length_, p_text_, text_length_ ) == 0 );
}
// ————————————————-<OK><テスト済み>
//【指定範囲の部分文字列】を切り出して返す。( substr() )
// ※【戻り値】を参照にすると、【ローカルのアドレス】が返る。
inline std::wstring SubString( const size_t start_index_, const size_t length_ )
{
return text.substr( start_index_, length_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を追加する。 ( append() )
// ※ std::wstring::value_type は、wchar_t 。
inline std::wstring& Add( const WCHAR* p_text_ )
{
return text.append( p_text_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を追加する。 ( append() )
inline std::wstring& Add( const WCHAR* p_text_ , const size_t length_ )
{
return text.append( p_text_, length_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を追加する。 ( append() )
inline std::wstring& Add( const std::wstring& text_ )
{
return text.append( text_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を追加する。 ( append() )
inline std::wstring& Add( const std::wstring& text_ , const size_t start_index_, const size_t length_ )
{
return text.append( text_, start_index_, length_ );
}
// ————————————————-<OK><テスト済み>
//【文字】を末尾に追加する。 ( push_back() )
inline void AddChar( const WCHAR char_ )
{
text.push_back( char_ );
}
// ————————————————-<OK><テスト済み>
//【指定した文字】を指定した文字数だけ追加する。 ( append() )
inline std::wstring& AddChar( const WCHAR char_, const size_t count_ )
{
return text.append( count_, char_ );
}
// ————————————————-<OK><テスト済み>
//【指定範囲の文字列】を追加する。( ポインタ版 ) ( append() )
// WCHAR src_text[] = L”かきくけこ”;
// std::wstring added_text = t1.Add( src_text + 1, src_text + 3 ); // “きく” が追加される。
inline std::wstring& Add( const WCHAR* p_src_start_, const WCHAR* p_src_end_ )
{
return text.append( p_src_start_, p_src_end_ );
}
// ————————————————-<OK><テスト済み>
//【指定範囲の文字列】を追加する。( イテレータ版 ) ( append() )
// std::wstring src_text( L”かきくけこ”);
// std::wstring::iterator itr = src_text.begin();
// std::wstring added_text = t1.Add( itr + 1, itr + 3 ); // “きく” が追加される。
inline std::wstring& Add( const Iterator src_start_itr_, const Iterator src_end_itr_ )
{
return text.append( src_start_itr_, src_end_itr_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )
inline std::wstring& Insert( const size_t index_, const WCHAR* p_text_ )
{
return text.insert( index_, p_text_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )
// text1.Insert( 1, L”かきくけこ”, 3 ); // 2文字目に、”かきく” が挿入される。( 引数3は、挿入する文字数 )
inline std::wstring& Insert( const size_t index_, const WCHAR* p_text_, const size_t text_length_ )
{
return text.insert( index_, p_text_, text_length_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )
inline std::wstring& Insert( const size_t index_, const std::wstring& text_ )
{
return text.insert( index_, text_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )
// std::wstring src( L”かきくけこ” );
// text1.InsertByRange( 1, src, 1, 2 ); // 2文字目に、”きく” を挿入する。
inline std::wstring& InsertByRange(
const size_t index_,
const std::wstring& text_,
const size_t text_offset_,
const size_t text_length_
)
{
return text.insert( index_, text_, text_offset_, text_length_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )
// ※【指定したイテレータの指す位置までの文字列】で初期化される。
//
// text1.Insert( text1.GetFirstItr() + 2 ); // 2文字目までの文字列になる。
// ※他のインスタンスのイテレーターを渡すとコケる。
// ※begin()で取得したイテレータをそのまま渡すとコケる。( 1文字目は、begin() + 1 )
//・使い道がよくわからない。おそらく使うことはない。
inline Iterator Insert( Iterator itr_ )
{
return text.insert( itr_ );
}
// ————————————————-<OK><テスト済み>
//【文字】を挿入する。 ( insert() )
//・【イテレータで指定した位置】に、【指定した文字】を挿入する。
inline Iterator InsertByChar( Iterator itr_, WCHAR char_ )
{
return text.insert( itr_, char_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )
//・上記に加えて、さらに【挿入する文字数】を指定できる。
inline void InsertByChar( Iterator itr_, WCHAR char_, const size_t count_ )
{
text.insert( itr_, count_, char_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )
// text1.InsertByChar( 1, L’か’, 3 );
//
// ・2文字目から、’か’ が 3文字、挿入される。( “あかかかいうえお” )
inline std::wstring& InsertByChar(
const size_t index_,
const WCHAR char_,
const size_t count_
)
{
return text.insert( index_, count_, char_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )
inline void InsertByRange( Iterator itr_, const WCHAR* p_src_start_, const WCHAR* p_src_end_ )
{
text.insert( itr_, p_src_start_, p_src_end_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )
inline void InsertByRange( Iterator dest_start_itr_, const Iterator src_start_itr_, const Iterator src_end_itr_ )
{
text.insert( dest_start_itr_, src_start_itr_, src_end_itr_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )
//・TInputIteratorには、読み取り専用のイテレータ型を指定する。
// STL::stringW t1( L”あいうえお” );
// std::string t2( “かきくけこ” );
// t1.InsertByRange<std::string::iterator>( t1.GetItr(1), t2.begin(), t2.end() );
//
// → “あきいうえお” とはならず、stringの箇所が文字化けしている。
// ( 要するに、挿入は成功したが、文字コードが異なるため、文字化けしている、 )
template<typename TInputIterator>
inline void InsertByRangeEx( Iterator itr_, TInputIterator src_start_itr_, TInputIterator src_end_itr_ )
{
text.insert( itr_, src_start_itr_, src_end_itr_ );
}
// ————————————————-<OK><テスト済み>
//【文字列の指定部分】を削除して返す。 ( erase() )
// text1.RemoveAt( 1, 2 ); // 2文字目以降の2文字が削除される。 ( “あいうえお” → “あえお” )
inline std::wstring& RemoveAt( const size_t index_, const size_t length_ )
{
return text.erase( index_, length_ );
}
// ————————————————-<OK><テスト済み>
//【指定indexの1文字】を削除し、【次の文字のイテレーター】を返す。( erase() )
// text1.Remove( text1.GetItr( 1 ) ); // 2文字目が削除される。
//
//・2文字目が削除されたので、3文字目が2文字目に移動する。
// 戻り値のイテレーターは、この文字を指している。
inline Iterator RemoveChar( Iterator itr_ )
{
return text.erase( itr_ );
}
// ————————————————-<OK><テスト済み>
//【文字列の指定範囲】を削除し、【次の文字のイテレーター】を返す。 ( erase() )
// text1.RemoveByRange( text1.GetItr(1), text1.GetItr(2) ); // 2文字目から3文字目の範囲 ( 2文字目 ) が削除される。
inline Iterator RemoveByRange( Iterator start_itr_, Iterator end_itr_ )
{
return text.erase( start_itr_, end_itr_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】をクリアする。 ( clear() )
inline void Clear(void)
{
text.clear();
}
// ————————————————-<OK><テスト済み>
// カラ文字列ならtrueを返す。 ( empty() )
inline bool IsEmpty(void)
{
return text.empty();
}
// ————————————————-<OK><テスト済み>
//【文字列の指定範囲】をコピーする。 ( substr() )
// ※戻り値が参照でないのは、ローカルのアドレスを含んだ参照を返すためである。
// ( 参照にしても動作はするが、コンパイル時に警告が表示される )
inline std::wstring Substring( const size_t index_, const size_t length_ )
{
return text.substr( index_, length_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】をコピーする。 (コピーした文字数を返す) ( _Copy_s() )
//・copy()が使いものにならないため、安全性の高い_Copy_s()を使用している。
// ( この手の_s系メソッドで、コピー先とコピー元の要素数を指定しているのは、バッファオーバーランを防止するためである )
inline WCHAR* Copy(void)
{
size_t src_length = text.length(); // コピー元の文字数を取得しておく。
WCHAR* p_dest = new WCHAR[ src_length + 1 ]; // コピー先の文字列バッファを確保する。( +1 は、終端のNULL文字 )
size_t writed_length = text._Copy_s( p_dest, src_length + 1, src_length, 0 ); // コピーする。
//
// p1: コピー先の文字列バッファへのポインタ。
// p2: コピー先の文字列バッファの要素数。( 文字数 )
// p3: コピー元の文字数。
// p4: コピーを開始するオフセット位置。( コピー元のindex )
//
// 戻り値: コピーされた文字数が返る。
p_dest[ src_length ] = NULL; // 終端にNULL文字を入れる。
return p_dest;
}
// ————————————————-<OK><テスト済み>
//【文字列】を交換する。 ( swap() )
inline void Swap( CStringW& text_ )
{
text.swap( text_.GetString() );
}
// ————————————————-<OK><テスト済み>
//【文字数】を変更する。 ( resize() )
// ・追加された要素は、0クリアされている。
// ( “あいうえお” → “あいうえお” )
// ・一般的には、NULL文字までが文字列とみなされるが、
// lengthで返る文字数には、増加分も含まれている。
// ( ただし、NULL文字なので、表示はされない )
inline void Resize( const size_t new_length_ ) // 新しい文字数。
{
text.resize( new_length_ );
}
// ————————————————-<OK><テスト済み>
//【文字数】を変更する。 ( resize() )
// text.ResizeEx( 10, L’無’ ); // → “あいうえお無無無無無”
inline void ResizeEx(
const size_t new_length_, // 新しい文字数。
const WCHAR default_char_ // 新規要素は、この文字で初期化される。
)
{
text.resize( new_length_, default_char_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
// 引数1~2の指定範囲を、指定文字列に置き換える。( ※一般的な、「検索→置換」とは別物 )
inline std::wstring& Replace(
const size_t index_, // 置換範囲のオフセット位置。 (置換先)
const size_t length_, // 置換範囲の文字数。 (置換先)
const WCHAR* p_src_text_ // 置き換える文字列。 (置換元)
)
{
return text.replace( index_, length_, p_src_text_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
inline std::wstring& Replace(
const size_t index_, // 置換範囲のオフセット位置。 (置換先)
const size_t length_, // 置換範囲の文字数。 (置換先)
const std::wstring& src_text_ // 置き換える文字列。 (置換元)
)
{
return text.replace( index_, length_, src_text_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
// STL::stringW text1( L”あいうえお” );
// std::wstring text2( L”かきくけこ” );
// text1.Replace( text1.GetItr(1), text1.GetItr(2), text2 ); // → “あかきくけこうえお”
inline std::wstring& Replace(
const Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
const Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const std::wstring& src_text_ // 置き換える文字列。 (置換元)
)
{
return text.replace( start_itr_, end_itr_, src_text_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
// STL::stringW text1( L”あいうえお” );
// text1.Replace( 1,2, L’■’, 3 ); // → “あ■■■えお”
inline std::wstring& ReplaceByChar(
const size_t index_, // 置換範囲のオフセット位置。 (置換先)
const size_t length_, // 置換範囲の文字数。 (置換先)
const WCHAR src_char_, // 置き換える文字。 (置換元)
const size_t src_char_count_ // 置き換える文字の文字数。(置換元)
)
{
return text.replace( index_, length_, src_char_count_, src_char_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字】に置換する。 ( replace() )
// STL::stringW text1( L”あいうえお” );
// text1.Replace( text1.GetItr(1), text1.GetItr(2), L’■’ ); // → “あ■■■うえお”
inline std::wstring& ReplaceByChar(
const Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
const Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const WCHAR src_char_, // 置き換える文字。 (置換元)
const size_t src_char_count_ // 置き換える文字の文字数。(置換元)
)
{
return text.replace( start_itr_, end_itr_, src_char_count_, src_char_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
// 指定範囲を、指定文字列の先頭から指定文字数の部分文字列で置き換える。
// STL::CStringW text1( L”あいうえお” );
// std::wstring text2( L”かきくけこ” );
// text1.Replace( 1, 2, L”かきくけこ”, 2 ); // → “あかきえお”
inline std::wstring& ReplaceByRange(
const size_t index_, // 置換範囲のオフセット位置。 (置換先)
const size_t length_, // 置換範囲の文字数。 (置換先)
const WCHAR* p_src_text_, // 置き換える文字列。 (置換元)
const size_t src_length_ // 置換範囲の文字数。 (置換元)
)
{
return text.replace( index_, length_, p_src_text_, src_length_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
// STL::CStringW text1( L”あいうえお” );
// std::wstring text2( L”かきくけこ” );
// text1.Replace( 1, 2, text2, 1, 2 ); // → “あきくえお”
inline std::wstring& ReplaceByRange(
const size_t index_, // 置換範囲のオフセット位置。 (置換先)
const size_t length_, // 置換範囲の文字数。 (置換先)
const std::wstring& src_text_, // 置き換える文字列。 (置換元)
const size_t src_offset_, // 置換範囲のオフセット位置。 (置換元)
const size_t src_length_ // 置換範囲の文字数。 (置換元)
)
{
return text.replace( index_, length_, src_text_, src_offset_, src_length_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
// STL::stringW text1( L”あいうえお” );
// text1.Replace( text1.GetItr(1), text1.GetItr(2), L”かきくけこ” ); // → “あかきくけこうえお”
inline std::wstring& ReplaceByRange(
const Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
const Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const WCHAR* p_src_text_ // 置き換える文字列。 (置換元)
)
{
return text.replace( start_itr_, end_itr_, p_src_text_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
// STL::stringW text1( L”あいうえお” );
// text1.Replace( text1.GetItr(1), text1.GetItr(2), L”かきくけこ” ); // → “あかきうえお”
inline std::wstring& ReplaceByRange(
const Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
const Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const WCHAR* p_src_text_, // 置き換える文字列。 (置換元)
const size_t src_length_ // 置換範囲の先頭からの文字数。(置換元)
)
{
return text.replace( start_itr_, end_itr_, p_src_text_, src_length_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
// STL::stringW text1( L”あいうえお” );
// WCHAR src[] = L”らりるれろ”;
// t1.ReplaceByRange( t1.GetItr(1), t1.GetItr(2), src + 1, src + 3 ); // → “あらりうえお”
inline std::wstring& ReplaceByRange(
Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const WCHAR* p_src_start_, // 置換範囲の始点ポインタ。 (置換元)
const WCHAR* p_src_end_ // 置換範囲の終点ポインタ。 (置換元)
)
{
return text.replace( start_itr_, end_itr_, p_src_start_, p_src_end_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
// STL::stringW t1( L”あいうえお” );
// STL::stringW t2( L”かきくけこ” );
// t1.ReplaceByRange( t1.GetItr(1), t1.GetItr(2), t2.GetItr(1), t2.GetItr(2) ); // → “あきうえお”
inline std::wstring& ReplaceByRange(
Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const Iterator src_start_itr_, // 置換範囲の始点イテレーター。 (置換元)
const Iterator src_end_itr_ // 置換範囲の終点イテレーター。 (置換元)
)
{
return text.replace( start_itr_, end_itr_, src_start_itr_, src_end_itr_ );
}
// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )
// STL::stringW t1( L”あいうえお” );
// STL::stringW t2( L”かきくけこ” );
// t1.ReplaceByRange<std::wstring::iterator>( t1.GetItr(1), t1.GetItr(2), t2.GetItr(1), t2.GetItr(2) ); // → “あきうえお”
template<class TInputIterator>
inline std::wstring& ReplaceByRange(
Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
TInputIterator src_start_itr_, // 置換範囲の始点イテレーター。 (置換元)
TInputIterator src_end_itr_ // 置換範囲の終点イテレーター。 (置換元)
)
{
return text.replace( start_itr_, end_itr_, src_start_itr_, src_end_itr_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find() )
// STL::stringW t1( L”あいうえお” );
//
// size_t result = text1.IndexOf( L’う’, 0 ); // 要素[0]から検索する。
//
// if ( result == wstring::npos ) // 該当indexが無い場合は、trueになる。
// else // 今回は、要素[2]が ‘う’ なので、2 が返る。
inline size_t IndexOf( const WCHAR char_, const size_t start_index_ = 0 )
{
return text.find( char_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find() )
// size_t result = text1.IndexOf( L”えお”, 0 ); // 3 が返る。
inline size_t IndexOf( const WCHAR* p_text_, const size_t start_index_ = 0 )
{
return text.find( p_text_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find() )
// size_t result = text1.IndexOf( L”えお”, 0, 4 ); // 4文字目まで判定する。( 結果は npos )
//
// ※ 4文字目の要素[3] には、’え’ があるが、
// 5文字目の要素[4] の ‘お’ が範囲外で判定されないため、nposを返す。
inline size_t IndexOf( const WCHAR* p_text_, const size_t start_index_, const size_t length_ )
{
return text.find( p_text_, start_index_, length_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find() )
inline size_t IndexOf( const std::wstring& text_, const size_t start_index_ = 0 )
{
return text.find( text_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字以外】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find_first_not_of() )
inline size_t NotIndexOf( const WCHAR char_, const size_t start_index_ )
{
return text.find_first_not_of( char_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find_first_not_of() )
inline size_t NotIndexOf( const WCHAR* p_text_, const size_t start_index_ )
{
return text.find_first_not_of( p_text_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find_first_not_of() )
inline size_t NotIndexOf( const WCHAR* p_text_, const size_t start_index_, const size_t length_ )
{
return text.find_first_not_of( p_text_, start_index_, length_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find_first_not_of() )
inline size_t NotIndexOf( const std::wstring& text_, const size_t start_index_ )
{
return text.find_first_not_of( text_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字】を検索し、【最後に見つかった箇所の先頭index】を返す。 ( find_last_of() )
inline size_t LastIndexOf( const WCHAR char_, const size_t start_index_ )
{
return text.find_last_of( char_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最後に見つかった箇所の先頭index】を返す。 ( find_last_of() )
inline size_t LastIndexOf( const WCHAR* p_text_, const size_t start_index_ )
{
return text.find_last_of( p_text_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最後に見つかった箇所の先頭index】を返す。 ( find_last_of() )
inline size_t LastIndexOf( const WCHAR* p_text_, const size_t start_index_, const size_t length_ )
{
return text.find_last_of( p_text_, start_index_, length_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最後に見つかった箇所の先頭index】を返す。 ( find_last_of() )
inline size_t LastIndexOf( const std::wstring& text_, const size_t start_index_ )
{
return text.find_last_of( text_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字以外】を検索し、【最後に見つかった箇所の先頭index】を返す。( find_last_not_of() )
inline size_t NotLastIndexOf( const WCHAR char_, const size_t start_index_ )
{
return text.find_last_not_of( char_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最後に見つかった箇所の先頭index】を返す。( find_last_not_of() )
inline size_t NotLastIndexOf( const WCHAR* p_text_, const size_t start_index_ )
{
return text.find_last_not_of( p_text_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最後に見つかった箇所の先頭index】を返す。( find_last_not_of() )
inline size_t NotLastIndexOf( const WCHAR* p_text_, const size_t start_index_, const size_t length_ )
{
return text.find_last_not_of( p_text_, start_index_, length_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最後に見つかった箇所の先頭index】を返す。( find_last_not_of() )
inline size_t NotLastIndexOf( const std::wstring text_, const size_t start_index_ )
{
return text.find_last_not_of( text_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字以外】を逆順に検索し、【最初に見つかった位置】を返す。( rfind() )
inline size_t IndexOf_Reverse( const WCHAR char_, const size_t start_index_ )
{
return text.rfind( char_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列以外】を逆順に検索し、【最初に見つかった位置】を返す。( rfind() )
inline size_t IndexOf_Reverse( const WCHAR* p_text_, const size_t start_index_ )
{
return text.rfind( p_text_, start_index_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列以外】を逆順に検索し、【最初に見つかった位置】を返す。( rfind() )
inline size_t IndexOf_Reverse( const WCHAR* p_text_, const size_t start_index_, const size_t length_ )
{
return text.rfind( p_text_, start_index_, length_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字列以外】を逆順に検索し、【最初に見つかった位置】を返す。( rfind() )
inline size_t IndexOf_Reverse( const std::wstring& text_, const size_t start_index_ )
{
return text.rfind( text_, start_index_ );
}
// —————————————————–<OK><テスト済み>
//【内部的に確保される要素数】を返す。 ( capacity() )
//・未設定の状態だと、要素数が設定されている。
inline size_t GetCapacity(void)
{
return text.capacity();
}
// —————————————————–<OK><テスト済み>
//【内部的に確保される要素数】を変更する。 ( reserve() )
// ※wstringは、内部的にメモリ領域を多めに確保していて、この値は、その際の要素数。
// 多めに見積もっておけば、要素数が拡張された際の、再確保&コピーをしなくて済む。
//
// ・この値は、wstring::capacity()で取得できる。
// ・多すぎる場合は、wstring::shrink_to_fit()で切り詰めることができる。
inline void SetCapacity( const size_t capacity_ )
{
text.reserve( capacity_ );
}
// ————————————————-<OK><テスト済み>
//【先頭のイテレータ】を返す。 ( begin() )
inline Iterator GetFirstItr(void)
{
return text.begin();
}
// ————————————————-<OK><テスト済み>
//【末尾のイテレータ】を返す。 ( end() )
inline Iterator GetLastItr(void)
{
return text.end();
}
// —————————————————–<OK><テスト済み>
// 逆順ループ時の【最初の要素([count-1])のイテレータ】を返す。( rbegin() )
inline RevIterator GetFirstItr_Rev(void)
{
return text.rbegin();
}
// —————————————————–<OK><テスト済み>
// 逆順ループ時の【最後の要素([0])のイテレータ】を返す。( rend() )
inline RevIterator GetLastItr_Rev(void)
{
return text.rend();
}
// ————————————————-
// #################################################
// 演算子のオーバーロード
// #################################################
// ————————————————-
// CString = instance + CString
inline std::wstring& operator+( std::wstring& text_ )
{
text += text_;
return text;
}
// ————————————————-
// instance += CString
inline void operator+=( std::wstring& text_ )
{
text += text_;
}
// ————————————————-
// instance = CString
inline void operator=( std::wstring& text_ )
{
text = text_;
}
// ————————————————-
// bool result = ( instance == CString )
inline bool operator==( std::wstring& text_ )
{
return (text == text_);
}
// ————————————————-
// #################################################
// static 関数
// #################################################
// ————————————————-
//【ワイド文字列】を、【Int32値】に変換して返す。( stol() )
//static inline int ToInt32(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0, // オフセット位置。
// const int base_ = 10 // 基数。規定値は10。( 10進数表記 )
// )
// {
//return std::stol( text_, start_index_, base_ );
// }
//// ————————————————-
////【ワイド文字列】を、【UInt32値】に変換して返す。( stoul() )
//static inline unsigned int ToUInt32(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0, // オフセット位置。
// const int base_ = 10 // 基数。規定値は10。( 10進数表記 )
// )
// {
// return std::stoul( text_, start_index_, base_ );
// }
//// ————————————————-
////【ワイド文字列】を、【Int64値】に変換して返す。( stoll() )
//static inline __int64 ToInt64(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0, // オフセット位置。
// const int base_ = 10 // 基数。規定値は10。( 10進数表記 )
// )
// {
// return std::stoll( text_, start_index_, base_ );
// }
//// ————————————————-
////【ワイド文字列】を、【UInt64値】に変換して返す。( stoull() )
//static inline unsigned __int64 ToUInt64(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0, // オフセット位置。
// const int base_ = 10 // 基数。規定値は10。( 10進数表記 )
// )
// {
// return std::stoull( text_, start_index_, base_ );
// }
//// ————————————————-
////【ワイド文字列】を、【float値】に変換して返す。( stof() )
//static inline float ToFloat(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0 // オフセット位置。
// )
// {
// return std::stof( text_, start_index_ );
// }
//// ————————————————-
////【ワイド文字列】を、【double値】に変換して返す。( stod() )
////・「long double」版のstold()には、「long」が付いているが、doubleと同じ64bit。
//static inline double ToDouble(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0 // オフセット位置。
// )
// {
// return std::stod( text_, start_index_ );
// }
//// ————————————————-
////【double値】を、【ワイド文字列】に変換して返す。( to_wstring() )
//static inline std::wstring FromDouble( long double value_ )
// {
// return std::to_wstring( value_ );
// }
//// ————————————————-
////【long long値】を、ワイド文字列に変換して返す。( to_wstring() )
//static inline std::wstring FromInt64( __int64 value_ )
// {
// return std::to_wstring( value_ );
// }
//// ————————————————-
////【unsigned long long】値を、ワイド文字列に変換して返す。( to_wstring() )
//static inline std::wstring FromUInt64( unsigned __int64 value_ )
// {
// return std::to_wstring( value_ );
// }
// ————————————————-
}; // end class
}; // end namespace
// ————————————————-
#endif
コンピュータ上で文字列を扱う場合は、
.NetやJavaには、string型という基本データ型があります。
// ——————————
// string型の文字列変数「namae」に、文字列を代入する。
string namae = “ハム太”;
// ——————————
ネイティブC/C++で書く場合でも、
STLを使っていい場合なら、std::string クラスがあるし、
MFCを使う場合は、CStringクラスを使えば、同じような事ができます。
しかし、WindowsAPI や、その他のCOMライブラリなどでは
これらのクラスは対応しておらず、直接渡すことはできません。
これらの関数の引数には、文字配列を渡す必要があります。
// ————————————–
char multi_text [] = “あいうえお”; // マルチバイト文字の配列。
wchar_t wide_text[] = L“あいうえお”; // ワイド文字の配列。
// ————————————–
大きく分けて、この二通りがあるんですが、
SJISで書く場合には、char型 (マルチバイト文字) を使い、
Unicodeで書く場合は、wchar_t 型 (ワイド文字) を使います。
あとで決めたい場合は、TCHAR型を使います。
TCHAR型は、_UNICODE定数が#defineされている場合は
wchar_t として解釈され、そうでない場合は、charとして解釈されます。
// ——————————-
// TCHAR型の定義
#ifdef _UNICODE
typedef wchar_t TCHAR
#elseif
typedef char TCHAR
#endif
// ——————————-
Cランタイムの関数やWindowsAPIの関数も、
文字列を扱うものは、2通り定義されていて、
たとえばMessageBox関数には、
ANSI (の日本語拡張のSJISなど、マルチバイト文字) に対応した MessageBoxA関数と、
Unicode(のUTF-16などワイド文字)に対応したMessageBoxW関数があり、
単に、「MessageBox」と書いた場合には、
渡された引数によって、切り替わるようになっています。
コンピューターの内部では、文字データは、
「文字コード」という番号で、記録されています。
顔文字などで有名な「ASCIIコードセット」は、
英数字と基本的な記号しか扱わないため、
1文字のコードを、0~127番までの7bitで記録しています。
( 1バイト固定であるので、「シングルバイト文字」という。
日本語版のasciiには、半角カナ文字があって、
161~223番を使用するため、8bit (1バイト) をフルに使う )
しかし、日本語環境では、ひらがな、カタカナに加えて、
膨大な数の漢字を使用するため、
1バイト ( 0~255 ) では到底足りません。
そこで登場するのがマルチバイト文字で、
一般的には、「SJISコードセット」が使用されますが、
( 日本語版のWindowsでは、日本語拡張版の「cp932コードセット」が標準。
つまり、特に指定しない場合は、char配列は、
「cp932の文字コードの配列」として解釈されるのです。)
これらのコード体系のデータでは、ASCIIコードに加えて、
2byte以上の文字が混在して記録されています。
このマルチバイト文字は、全角文字が使用できる一方で、
—————————————–
・1文字におおよそ3バイト使用する。
・何文字目か、わかりにくい。( 判定する手間がかかる )
—————————————–
などの難点もあります。
これに対して、ワイド文字では、
1文字を、おおむね2バイトで記録します。
( 半角文字では、未使用の1バイトが0で埋められます。)
このワイド文字は、おもにUnicodeで使用されます。
Unicodeは、世界中の文字を
混在して記録できるようにするために制定された
ワールドワイドなコード体系で、正確には
1文字を4バイトで記録している文字もあります。
ただし、これらの文字はまだ、API側で未対応のため、
MessageBoxWに渡しても、文字化けしてしまいます。
( 普段は使わないような難解な漢字なので、無視しても無問題 )
これに対応するためなのか、どうかわかりませんが、
1文字を4バイトで記録しているファイルフォーマットがあります。
————————————–
「UTF-8」 … マルチバイト文字のUnicode。
「UTF-16」… 1文字を2バイトで記録しているUnicode。
「UTF-32」 … 1文字を4バイトで記録しているUnicode。 ←コレ
————————————–
テキストファイルの場合は、
先頭に「BOM」(ByteOrderMark) が記録されていて、
テキストエディタなどで読み込まれる際には、これに応じて
どの方式で記録されたデータかを判別して表示しています。
しかし、必ずしもBOMが記録されているとは限らないため、
その場合には、エディタがどのコードセットのデータなのか判別できず、
文字化けして表示されてしまいます。
Unicodeは本来、「文字化け」を解消しようとして
制定された統一規格だったのですが、
あとで追加された文字によって、
2バイト ( 0~65535 ) では足りなくなり、
前述の、ファイルへの記録方式のこともあって、
完全な問題解決には至っていません。
UNIXやMacではUTF32BEが使用されているようで、
将来的にはUTF32BEで統一されるのかも知りません。
( 「BE」は、「ビックエンディアン」の略。
Windowsは、「LE」(リトルエンディアン)方式でファイルに記録するので、
2バイト以上の値をファイルに書き込んだり読み込む際には、
1バイト単位で逆順に並べなおして複合する。)
Windowsでは、SJIS(cp932)が標準であるため、
char配列でSJISを使うことが多かったのですが、
現在では、Unicodeの使用が推奨されています。
ちなみに、wchar_t ( ワイド文字 ) を使用する場合は、
「Unicodeの配列である」と解釈されるようです。
ここまでの内容が本になりました。↓
http://p.booklog.jp/book/74234
出版記念パーティーでもしょうかな。^^
文字列は、文字コードと含めて一緒に出します。
一応予告をしておくと、
KFCのコアな部分は後回しにして、
WIC MME MSXML など、オマケ部分から書いていきます。