Windows Runtime Cpp 文字列操作 新しいページはコチラ
提供: yonewiki
(→応用:文字列配列のソート std::sortとstd::foreachの利用) |
(→応用:文字列配列のソート std::sortとstd::foreachの利用) |
||
| 1,224行: | 1,224行: | ||
| − | == '''応用:文字列配列のソート std::sortとstd:: | + | == '''応用:文字列配列のソート std::sortとstd::for_eachの利用''' == |
| − | STL(Standard Template Liblary) | + | STL(Standard Template Liblary)で準備されているソート関数を利用する例を示します。文字列配列を扱うためのstd::vectorテンプレートとクイックソート処理を行うstd::sortと配列を一覧するstd::for_eachを使えば、WindowsCompareStringOrdinal関数の文字列比較を利用して文字列配列のソート処理ができます。sort関数の第3引数は[]()->{}というカタチをとるラムダ式による処理が与えられています。ラムダ式についての詳細は[[Cpp ラムダ式]]を参照して下さい。サンプルのラムダ式はsort部では()引数部に2つのHSTRING型のaという変数とbという変数が引数になっています。->boolという部分でラムダ式の処理結果として返す値の変数の型を指定しています。{}内がラムダ式の処理値です。[]は内の値はキャプチャと呼ばれる外部を参照する変数を指定するものです。sort処理のクイックソートにおける前方値と後方値という位置づけの再帰的な引数が処理部に渡される仕組みで、処理部では、前方値と後方値の大きさを比較して、bool型の値を返却することになっています。比較の結果、大きい値が前方にあってtrue返すような関数なら降順に整列されます。大きい値が前方にある場合、WindowsCompareStringOrdinalの結果はtrueなので、そのまま、この結果を返すか、サンプルのようにr>0と結果値rがtrueならtrueになるような比較の結果を返却する式をreturn文で指定しています。 |
| + | 2つめのfor_each関数のラムダ式は返却値無しで引数となるすべての配列値をひとつづつ処理するような内容のラムダ式としての処理部があれば良いので、サンプルのような処理になっています。HSTRING型の文字操作は先の項目にあげたような処理のみに限られ、変数が保持している文字列の内容そのものを変えることはできません。ですが、サンプルのようなvectorテンプレートの配列で順番を入れ替えるのはHSTRING型の文字列値をかえることなく配列の順番を意味する配列番号がもつHSTRING変数のアドレス変数を保持しなおすような整列であって中身を入れ替えるわけではないので、整列が可能なのです。お間違いなきよういただければと思います。 | ||
| + | |||
| + | <syntaxhighlight lang="cpp" line start="1"> | ||
| + | #include <locale.h> | ||
| + | #include <wchar.h> | ||
| + | #include <stdio.h> | ||
| + | #include <vector> | ||
| + | #include <algorithm> | ||
| + | #include <crtdbg.h> | ||
| + | #include <roapi.h> | ||
| + | #include <winstring.h> | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | HRESULT hr; | ||
| + | setlocale(LC_ALL, ""); | ||
| + | |||
| + | hr = RoInitialize(RO_INIT_TYPE::RO_INIT_MULTITHREADED); | ||
| + | if (FAILED(hr)) { | ||
| + | wprintf_s(L"初期化に失敗しました。\n"); | ||
| + | _CrtDbgBreak(); | ||
| + | return 0; | ||
| + | } | ||
| + | else { | ||
| + | wprintf_s(L"初期化に成功しました。\n"); | ||
| + | } | ||
| + | |||
| + | const wchar_t *pcStrList[] = { | ||
| + | L"04_文字列ネイティブ変数参照連動", | ||
| + | L"09_文字列置換_置換変数指定", | ||
| + | L"05_文字列結合", | ||
| + | L"深田 恭子", | ||
| + | L"小西 真奈美", | ||
| + | L"広瀬 すず", | ||
| + | L"広瀬 アリス", | ||
| + | L"土屋 太鳳", | ||
| + | nullptr | ||
| + | }; | ||
| + | |||
| + | std::vector<HSTRING> hStringList; | ||
| + | for (int i = 0; pcStrList[i]; ++i) | ||
| + | { | ||
| + | HSTRING HSTRING_StrTemp; | ||
| + | const wchar_t *cStr = pcStrList[i]; | ||
| + | hr = WindowsCreateString(cStr, wcslen(cStr), &HSTRING_StrTemp); | ||
| + | if (FAILED(hr)) | ||
| + | { | ||
| + | wprintf_s(L"文字列の生成に失敗しました\n"); | ||
| + | _CrtDbgBreak(); | ||
| + | return 0; | ||
| + | } | ||
| + | else { | ||
| + | wprintf_s(L"文字列の生成に成功しました\n"); | ||
| + | } | ||
| + | |||
| + | hStringList.push_back(HSTRING_StrTemp); | ||
| + | |||
| + | hr = WindowsDeleteString(HSTRING_StrTemp); | ||
| + | if (FAILED(hr)) { | ||
| + | wprintf_s(L"文字列の削除に失敗しました\n"); | ||
| + | _CrtDbgBreak(); | ||
| + | } | ||
| + | else { | ||
| + | wprintf_s(L"文字列の削除に成功しました\n"); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | std::sort( | ||
| + | hStringList.begin(), | ||
| + | hStringList.end(), | ||
| + | [hStringList, &pcStrList](const HSTRING a, const HSTRING b)->bool { | ||
| + | int r; | ||
| + | HRESULT hr = WindowsCompareStringOrdinal(a, b, &r); | ||
| + | wprintf_s(L"\n"); | ||
| + | wprintf_s(L"a = %s,b = %s %d(", WindowsGetStringRawBuffer(a, nullptr), WindowsGetStringRawBuffer(b, nullptr), r); | ||
| + | if (r > 0) { | ||
| + | wprintf_s(L">)\n"); | ||
| + | } | ||
| + | else if (r < 0) { | ||
| + | wprintf_s(L"<)\n"); | ||
| + | } | ||
| + | else { | ||
| + | wprintf_s(L"=)\n"); | ||
| + | } | ||
| + | |||
| + | if (FAILED(hr)) { | ||
| + | wprintf_s(L"文字列の比較に失敗しました\n"); | ||
| + | _CrtDbgBreak(); | ||
| + | } | ||
| + | else { | ||
| + | //wprintf_s(L"文字列の比較に成功しました\n"); | ||
| + | } | ||
| + | wprintf_s(L"\n"); | ||
| + | for (size_t i = 0; i < hStringList.size(); i++) { | ||
| + | wprintf_s(L"%s,", WindowsGetStringRawBuffer(hStringList.at(i), nullptr)); | ||
| + | } | ||
| + | wprintf_s(L"\n"); | ||
| + | |||
| + | for (int i = 0; pcStrList[i]; i++) { | ||
| + | wprintf_s(L"%s,", pcStrList[i]); | ||
| + | } | ||
| + | wprintf_s(L"\n"); | ||
| + | return r > 0; | ||
| + | } | ||
| + | ); | ||
| + | |||
| + | wprintf_s(L"\n"); | ||
| + | std::for_each( | ||
| + | hStringList.begin(), | ||
| + | hStringList.end(), | ||
| + | [](HSTRING HSTRING_Str)->void{ | ||
| + | wprintf_s(L"%s\n", WindowsGetStringRawBuffer(HSTRING_Str, nullptr)); | ||
| + | |||
| + | HRESULT hr = WindowsDeleteString(HSTRING_Str); | ||
| + | if (FAILED(hr)){ | ||
| + | wprintf_s(L"文字列の削除に失敗しました\n"); | ||
| + | _CrtDbgBreak(); | ||
| + | } | ||
| + | else { | ||
| + | //wprintf_s(L"文字列の削除に成功しました\n"); | ||
| + | } | ||
| + | } | ||
| + | ); | ||
| + | |||
| + | |||
| + | RoUninitialize(); | ||
| + | _wsystem(L"pause"); | ||
| + | } | ||
| + | |||
| + | </syntaxhighlight> | ||
| + | |||
| + | 実行結果 | ||
初期化に成功しました。 | 初期化に成功しました。 | ||
文字列の生成に成功しました | 文字列の生成に成功しました | ||