2016-07-19 14 views
0
struct ci_char_traits : public std::char_traits<char> 
{ 
    static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); } 
    static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); } 
    static bool lt(char c1, char c2) { return toupper(c1) < toupper(c2); } 

    static int compare(const char* s1, const char* s2, size_t n); 
    static const char* find(const char* s, int n, char a); 
}; 

using ci_string = std::basic_string<char, ci_char_traits>; 

私は大文字と小文字を区別しない文字列比較を扱うのに役立つこのchar_traits派生関数を使っています。文字リテラルからci_stringsを構築するときは完璧にうまく動作しますが、私はしばしば1つまたは2つのstd :: stringsを持つ状況に直面しており、大文字と小文字を区別しないで比較したいと思います。 std :: stringからci_stringに変換するためのカスタムコンストラクタや代入/変換演算子を書く方法はありますか?それとも、std :: stringsを反復して各文字のtolowerを呼び出す以外の方法はありませんか?カスタム文字列型のコンストラクタ/代入演算子オーバーロードの書き方は?

+0

'c_str()'を使用しますか? – Arunmu

答えて

2

std::stringからci_stringを作成するには、イテレータ範囲を使用するコンストラクタを使用できます。これはstd::stringを反復処理し、ci_stringにその文字のコピーを格納します:

std::string foo = "test"; 
ci_string bar(foo.begin(), foo.end()); 

これは、任意のbasic_string専門限り(この場合はchar)基本となるタイプのために動作しますが、同じです。しかしstd::wstringでこれを行うことは望ましくありません.wchar_tを使用しているため、間違った変換が行われます。コメントで指摘したように

また、あなたもconst char*を取り、カウントコンストラクタを使用してci_stringを構築することができます。

std::string foo = "test"; 
ci_string bar(foo.c_str(), foo.length()); 

これは、あなたが使用するすべての「文字列」を使用することができませんでし利点を持っていますフードの下のchar以外のもの、たとえばstd::wstring

+0

また、 'char *'と長さを入力として持つコンストラクタを使用することもできます。 'ci_string bar(foo.c_str()、foo.size());'これは 'ci_string' 'wchar_t *'は 'char *'に代入することができないので、 'std :: wstring'から削除します。 –

+0

@RemyLebeau良い点。 'const char *'のためのコンストラクタを持っているのでサイズは必要ありません – NathanOliver

+0

はい、そのコンストラクタは 'char'要素を手動で数えなければなりません。元の文字列はすでに存在する文字列を知っているので、その値がわかっているときにその値をコンストラクタに渡す方が良いでしょう。 –

関連する問題