Windows Runtime Cpp 文字列操作
概要
文字列操作関数としてHSTRING型というのが提供されていて、WindowsRuntime関数では、この文字列型を利用するので、この文字列型を一通り覚える必要があるようです。HSTRING型の変数に保持された文字列は、変更されることがない文字列という感覚で使うので、初期値設定したり、くっつけたりという、操作はできても、文字列を保持させたHSTRING変数の中身を変更するような操作はできません。検索してもHSTRINGに関する情報はほとんど出てこないので、死んだ技術なのかなと思ってしまいます。負のレガシー的な記事としてきっちり説明文書をのこしておきましょ♪
生成 WindowsCreateString(関数)
wchar_t型なんかの、c++言語の文字列操作で使われたような文字列型が生成関数の引数として使われます。例えば以下のようなプログラムで、生成することができます。文字列操作に関する説明はC 文字列操作とか、そのあたりで連携している項目を参考にして下さい。基礎知識がない人にとっては膨大な基礎の知識が必要になります。L""って何?とか、selocaleって何?という疑問については、ここでは記述しません。37,39行目についてのHSTRING文字列操作関数でまだ説明していない関数なので、後述します。
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#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");
}
HSTRING hStr;
wchar_t cStr[] = L"ワイド文字列";
size_t length = wcslen(cStr);
hr = WindowsCreateString(cStr, length, &hStr);
if (FAILED(hr)) {
wprintf_s(L"HSTRING文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"HSTRING文字列の生成に成功しました。\n");
}
wprintf_s(L"\n★%s\n\n", WindowsGetStringRawBuffer(hStr, nullptr));
hr = WindowsDeleteString(hStr);
if (FAILED(hr)) {
wprintf_s(L"hStr文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr文字列の削除に成功しました。\n");
}
RoUninitialize();
_wsystem(L"pause");
return 0;
}
実行結果の出力結果
初期化に成功しました。 HSTRING文字列の生成に成功しました。 ★ワイド文字列 hStr文字列の削除に成功しました。
という長いサンプルになってしまいましたが、こういう感じですね。使われているのは、27行目です。
- WindowsCreateString(文字列配列先頭アドレス, 文字列調, HSTRING型変数のアドレス);
引数:
- 第1引数:文字列配列先頭アドレス サンプルプログラムでは wchar_t の配列cStrという変数で初期化文字列を与えて生成したものの先頭アドレスを引数にしています。cStr[]配列の先頭アドレスはcStrになります。管理人の場合はpcStrという変数名を使うのが流儀です。配列での初期化をするとポインタ変数としてcStrを宣言した意識が薄れる感じはありますが、そこまで神経質なプログラマはあまりみかけませんね。自分で覚えとけってことっすかね。
- 第2引数:文字列の長さをwcslen(cStr)で取得したものをsize_t型の変数lengthに取得していますので、サンプルではlengthを引数にしています。
- 第3引数:HSTRING型変数のアドレスを引数にします。 サンプルでは実体化されて宣言されたHSTRING型のhStrのアドレスを受け取るため&hStrとしています。
戻り値:HRESULT型の列挙子です。S_OKが返ってくることになっています。数字が返ってくるだけの構造なので、適当な整数型の変数でも受け取れると思います。
削除 WindowsDeleteString(関数)
生成のところのサンプルで示しましたが、HSTRING文字列をWindowsCreateStringで生成された文字列変数は削除を宣言するまでメモリが消費されたままになりますので、使い終わったら、削除する関数を使って解放するのが普通です。
- WindowsCreateString(HSTRING型変数);
引数:
- 第1引数:削除・メモリ解放したいHSTRING文字列変数を付与する。サンプルでは39行目で使われていて、引数はhStrとなっています。
文字列値格納配列先頭アドレス取得 WindowsGetStringRawBuffer(関数)
生成のところのサンプルで示しましたが、C++の文字列操作関数なんかで必要な文字列型の先頭アドレスを必要とする関数のために、HSTRING型文字列で格納された文字列を格納している文字列配列の先頭アドレスを取得する関数です。
- WindowsGetStringRawBuffer(HSTRING型変数,取得文字数);
引数:
- 第1引数:削除・文字列値を取得したいHSTRING文字列変数を付与する。サンプルでは37行目で使われていて、引数はhStrとなっています。
- (第2引数)オプション:取得した文字列配列格納の先頭アドレスから何文字取得するかを指定する。指定しない場合はnullptrと指定するとよいです。
文字列のネイティブ変数参照連動 WindowsCreateReference(関数)
文字列を複製する関数です。コピーとは少し違う動作をします。まずは使い方に関する説明とサンプルと動作結果を示します。
- WindowsCreateReference(PCWSTR型配列変数先頭アドレス,文字列長さ,実体のあるSTRING_HEADER型アドレス変数,実体のあるHSTRING型アドレス変数);
引数:
- 第1引数:文字列値を参照したいPCWSTR変数(ワイド文字列の配列変数の先頭アドレス)を付与する。サンプルでは38行目で使われていて、引数はcStrとなっています。
- 第2引数:第1引数で指定したPCWSTR変数の参照したい文字数を指定する。サンプルでは38行目で使われていて、引数はlengthとなっています。
- 第3引数:第1引数で指定した文字列値からあたらしく参照したいHSTRING変数のためのSTRING_HEADER型ポインタ変数です。サンプルでは38行目で使われていて、引数は&headerとなっています。
- 第4引数:文字列値を参照したいPCWSTR変数(ワイド文字列の配列変数の先頭アドレス)を付与する。サンプルでは38行目で使われていて、引数はcStrとなっています。
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#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");
}
HSTRING hStr, hRefStr;
HSTRING_HEADER header;
wchar_t cStr[] = L"ワイド文字列 ";
size_t length = wcslen(cStr);
hr = WindowsCreateString(cStr, length, &hStr);
if (FAILED(hr)) {
wprintf_s(L"hString文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hString文字列の生成に成功しました。\n");
}
hr = WindowsCreateStringReference(cStr, length, &header, &hRefStr);
if (FAILED(hr)) {
wprintf_s(L"hString文字列参照の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hString文字列参照の生成に成功しました。\n");
}
PCWSTR hStrBuffer = WindowsGetStringRawBuffer(hStr, nullptr);
wprintf_s(L"%s\n", hStrBuffer);
wprintf_s(L"Address=%p\n\n", hStrBuffer);
PCWSTR hRefStrBuffer = WindowsGetStringRawBuffer(hRefStr, nullptr);
wprintf_s(L"%s\n", hRefStrBuffer);
wprintf_s(L"Address=%p\n\n", hRefStrBuffer);
wprintf_s(L"%s\n", cStr);
wprintf_s(L"Address=%p\n\n", cStr);
swprintf_s(cStr, L"ワイド文字列の再設定をswprintf_s関数で実施。");
wprintf_s(L"%s\n", hRefStrBuffer);
wprintf_s(L"Address=%p\n\n", hRefStrBuffer);
hr = WindowsDeleteString(hStr);
if (FAILED(hr)) {
wprintf_s(L"hStr文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hRefStr);
if (FAILED(hr)) {
wprintf_s(L"hRefStr文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hRefStr文字列の削除に成功しました。\n");
}
RoUninitialize();
_wsystem(L"pause");
return 0;
}
実行結果の出力結果
初期化に成功しました。 hString文字列の生成に成功しました。 hString文字列参照の生成に成功しました。 ワイド文字列 Address=00105018 ワイド文字列 Address=007FF9C4 ワイド文字列 Address=007FF9C4 ワイド文字列の再設定をswprintf_s関数で実施。 Address=007FF9C4 hStr文字列の削除に成功しました。 hRefStr文字列の削除に成功しました。 続行するには何かキーを押してください . . .
文字列結合 WindowsConcatString(関数)
2つのHSTRING型文字列を結合し、3つ目のHSTRING変数に新しく結合後の変数を設定する関数です。まずは使い方に関する説明とサンプルと動作結果を示します。
- WindowsConcatString(HSTRING変数_結合の前半部分,HSTRING変数_結合の後半部分,実体のあるHSTRING型アドレス変数_結合させた文字列);
引数:
- 第1引数:結合したい文字列の前半部分を保持したHSTRING変数。サンプルでは49行目で使われていて、引数はhStr1となっています。
- 第2引数:結合したい文字列の後半部分を保持したHSTRING変数。サンプルでは49行目で使われていて、引数はhStr2となっています。
- 第3引数:結合した文字列を格納させるHSTRINGのアドレス変数。サンプルでは49行目で使われていて、引数はhStr3となっています。
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#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");
}
HSTRING hStr1, hStr2, hStr3, hRefStr;
HSTRING_HEADER header;
wchar_t cStr1[] = L"ワイド文字列:前半 ";
wchar_t cStr2[] = L"ワイド文字列:後半 ";
size_t length = wcslen(cStr1);
hr = WindowsCreateString(cStr1, length, &hStr1);
if (FAILED(hr)) {
wprintf_s(L"hString文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hString文字列の生成に成功しました。\n");
}
hr = WindowsCreateString(cStr2, length, &hStr2);
if (FAILED(hr)) {
wprintf_s(L"hString文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hString文字列の生成に成功しました。\n");
}
hr = WindowsConcatString(hStr1, hStr2, &hStr3);
if (FAILED(hr)) {
wprintf_s(L"hString文字列結合の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hString文字列結合の生成に成功しました。\n");
}
wprintf_s(L"%s\n", WindowsGetStringRawBuffer(hStr3, nullptr));
wprintf_s(L"Address=%p\n\n", hStr3);
hr = WindowsCreateStringReference(cStr1, length, &header, &hRefStr);
if (FAILED(hr)) {
wprintf_s(L"hString文字列参照の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hString文字列参照の生成に成功しました。\n");
}
PCWSTR hStrBuffer = WindowsGetStringRawBuffer(hStr1, nullptr);
wprintf_s(L"%s\n", hStrBuffer);
wprintf_s(L"Address=%p\n\n", hStrBuffer);
PCWSTR hRefStrBuffer = WindowsGetStringRawBuffer(hRefStr, nullptr);
wprintf_s(L"%s\n", hRefStrBuffer);
wprintf_s(L"Address=%p\n\n", hRefStrBuffer);
wprintf_s(L"%s\n", cStr1);
wprintf_s(L"Address=%p\n\n", cStr1);
swprintf_s(cStr1, L"ワイド文字列の再設定をswprintf_s関数で実施。");
wprintf_s(L"%s\n", hRefStrBuffer);
wprintf_s(L"Address=%p\n\n", hRefStrBuffer);
hr = WindowsDeleteString(hStr3);
if (FAILED(hr)) {
wprintf_s(L"hStr3文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr3文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hStr2);
if (FAILED(hr)) {
wprintf_s(L"hStr2文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr2文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hRefStr);
if (FAILED(hr)) {
wprintf_s(L"hRefStr文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hRefStr文字列の削除に成功しました。\n");
}
RoUninitialize();
_wsystem(L"pause");
return 0;
}
実行結果の出力結果
初期化に成功しました。 hString文字列の生成に成功しました。 hString文字列の生成に成功しました。 hString文字列結合の生成に成功しました。 ワイド文字列:前半 ワイド文字列:後半 Address=00DE9788 hString文字列参照の生成に成功しました。 ワイド文字列:前半 Address=00DE4810 ワイド文字列:前半 Address=00AFFCA4 ワイド文字列:前半 Address=00AFFCA4 ワイド文字列の再設定をswprintf_s関数で実施。 Address=00AFFCA4 hStr3文字列の削除に成功しました。 hStr2文字列の削除に成功しました。 hStr1文字列の削除に成功しました。 hRefStr文字列の削除に成功しました。 続行するには何かキーを押してください . . .
文字列の抽出_指定始点~終端 WindowsSubstring(関数)
HSTRING型文字列の特定の位置から終端までを抽出するための関数です。右側抽出ですね。まずは使い方に関する説明とサンプルと動作結果を示します。
- WindowsSubstring(HSTRING変数,抽出開始位置_始点位置0~カウント,実体のあるHSTRING型アドレス変数);
引数:
- 第1引数:抽出対象のHSTRING変数。サンプルでは37行目で使われていて、引数はhStr1となっています。
- 第2引数:抽出対象の文字列の先頭文字位置を0として、抽出開始の位置を数値で指定する。サンプルでは37行目で使われていて、引数は10となっています。
- 第3引数:抽出した文字列を格納させるHSTRINGのアドレス変数。サンプルでは37行目で使われていて、引数は&hStr2となっています。
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#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");
}
HSTRING hStr1, hStr2;
wchar_t cStr1[] = L"ワイド文字列変数890サンプル567";
size_t length = wcslen(cStr1);
hr = WindowsCreateString(cStr1, length, &hStr1);
if (FAILED(hr)) {
wprintf_s(L"hString文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hString文字列の生成に成功しました。\n");
}
hr = WindowsSubstring(hStr1, 10, &hStr2);
if (FAILED(hr)) {
wprintf_s(L"部分文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"部分文字列の生成に成功しました。\n");
}
wprintf_s(L"部分文字列=%s\n", WindowsGetStringRawBuffer(hStr2, nullptr));
hr = WindowsDeleteString(hStr2);
if (FAILED(hr)) {
wprintf_s(L"hStr2文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr2文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の削除に成功しました。\n");
}
RoUninitialize();
_wsystem(L"pause");
return 0;
}
実行結果の出力結果
初期化に成功しました。 hString文字列の生成に成功しました。 部分文字列の生成に成功しました。 部分文字列=0サンプル567 hStr2文字列の削除に成功しました。 hStr1文字列の削除に成功しました。 続行するには何かキーを押してください . . .
文字列の抽出_指定始点~指定文字数 WindowsSubstringWithSpecifiedLength(関数)
HSTRING型文字列の特定の位置から指定の文字数を抽出するための関数です。中間抽出の始点+距離型ですね。まずは使い方に関する説明とサンプルと動作結果を示します。
- WindowsSubstringWithSpecifiedLength(HSTRING変数,抽出開始位置_始点位置0~カウント,抽出終了位置_始点位置からの文字数,実体のあるHSTRING型アドレス変数);
引数:
- 第1引数:抽出対象のHSTRING変数。サンプルでは37行目で使われていて、引数はhStr1となっています。
- 第2引数:抽出対象の文字列の先頭文字位置を0として、抽出開始の位置を数値で指定する。サンプルでは37行目で使われていて、引数は10となっています。
- 第3引数:抽出対象の文字列の終端位置を開始位置からの文字数で指定する。サンプルでは37行目で使われていて、引数は5となっています。
- 第4引数:抽出した文字列を格納させるHSTRINGのアドレス変数。サンプルでは37行目で使われていて、引数は&hStr2となっています。
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#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");
}
HSTRING hStr1, hStr2;
wchar_t cStr1[] = L"ワイド文字列変数890サンプル567";
size_t length = wcslen(cStr1);
hr = WindowsCreateString(cStr1, length, &hStr1);
if (FAILED(hr)) {
wprintf_s(L"hString文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hString文字列の生成に成功しました。\n");
}
hr = WindowsSubstringWithSpecifiedLength(hStr1, 10, 5, &hStr2);
if (FAILED(hr)) {
wprintf_s(L"部分文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"部分文字列の生成に成功しました。\n");
}
wprintf_s(L"部分文字列=%s\n", WindowsGetStringRawBuffer(hStr2, nullptr));
hr = WindowsDeleteString(hStr2);
if (FAILED(hr)) {
wprintf_s(L"hStr2文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr2文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の削除に成功しました。\n");
}
RoUninitialize();
_wsystem(L"pause");
return 0;
}
実行結果の出力結果
初期化に成功しました。 hString文字列の生成に成功しました。 部分文字列の生成に成功しました。 部分文字列=0サンプル hStr2文字列の削除に成功しました。 hStr1文字列の削除に成功しました。 続行するには何かキーを押してください . . .
文字列の置換_置換検索文字と置換後文字変数個別指定 WindowsReplaceString(関数)
置換対象のHSTRING型文字列に対して、置換対象の検索文字を指定し、指定された置換後文字に置き換えるための関数です。まずは使い方に関する説明とサンプルと動作結果を示します。
- WindowsReplaceString(HSTRING変数,HSTRING変数_検索文字列,HSTRING変数_置換文字列,実体のあるHSTRING型アドレス変数);
引数:
- 第1引数:置換対象のHSTRING変数。サンプルでは62行目で使われていて、引数はhStr1となっています。
- 第2引数:HSTRING変数で指定する検索文字列。サンプルでは62行目で使われていて、引数はhStr2となっています。
- 第3引数:HSTRING変数で指定する置換文字列。サンプルでは62行目で使われていて、引数はhStr3となっています。
- 第4引数:置換後の文字列を格納させるHSTRINGのアドレス変数。サンプルでは62行目で使われていて、引数は&hStr4となっています。
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#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");
}
HSTRING hStr1, hStr2, hStr3, hStr4;
const wchar_t *cStr1 = L"1234567890";
const wchar_t *cStr2 = L"34";
const wchar_t *cStr3 = L"43";
size_t length = wcslen(cStr1);
length = wcslen(cStr1);
hr = WindowsCreateString(cStr1, length, &hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の生成に成功しました。\n");
}
length = wcslen(cStr2);
hr = WindowsCreateString(cStr2, length, &hStr2);
if (FAILED(hr)) {
wprintf_s(L"hStr2文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr2文字列の生成に成功しました。\n");
}
length = wcslen(cStr3);
hr = WindowsCreateString(cStr3, length, &hStr3);
if (FAILED(hr)) {
wprintf_s(L"hStr3文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr3文字列の生成に成功しました。\n");
}
hr = WindowsReplaceString(hStr1, hStr2, hStr3, &hStr4);
if (FAILED(hr)) {
wprintf_s(L"部分文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"置換文字列の生成に成功しました。\n");
}
wprintf_s(L"元文字列 =%s 検索文字列=%s 置換文字列=%s\n", WindowsGetStringRawBuffer(hStr1, nullptr), WindowsGetStringRawBuffer(hStr2, nullptr), WindowsGetStringRawBuffer(hStr3, nullptr));
wprintf_s(L"置換後文字列=%s\n", WindowsGetStringRawBuffer(hStr4, nullptr));
wprintf_s(L"hStr1_Address=%p, hStr2_Address=%p, hStr3_Address=%p, hStr4_Address=%p\n", hStr1, hStr2, hStr3, hStr4);
hr = WindowsDeleteString(hStr4);
if (FAILED(hr)) {
wprintf_s(L"hStr4文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr4文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hStr3);
if (FAILED(hr)) {
wprintf_s(L"hStr3文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr3文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hStr2);
if (FAILED(hr)) {
wprintf_s(L"hStr2文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr2文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の削除に成功しました。\n");
}
RoUninitialize();
_wsystem(L"pause");
return 0;
}
実行結果の出力結果
初期化に成功しました。 hStr1文字列の生成に成功しました。 hStr2文字列の生成に成功しました。 hStr3文字列の生成に成功しました。 置換文字列の生成に成功しました。 元文字列 =1234567890 検索文字列=34 置換文字列=43 置換後文字列=1243567890 hStr1_Address=010E5A90, hStr2_Address=010D5AB0, hStr3_Address=010D54D0, hStr4_Address=010E6190 hStr4文字列の削除に成功しました。 hStr3文字列の削除に成功しました。 hStr2文字列の削除に成功しました。 hStr1文字列の削除に成功しました。 続行するには何かキーを押してください . . .
文字列の複製 WindowsDuplicateString(関数)
文字列を複製する関数です。コピーとは少し違う動作をします。まずは使い方に関する説明とサンプルと動作結果を示します。
- WindowsDuplicateString(HSTRING型変数,HSTRING型ポインタ変数);
引数:
- 第1引数:文字列値を複製したいHSTRING文字列変数を付与する。サンプルでは41行目で使われていて、引数はhStr1となっています。
- 第2引数:第1引数で指定した文字列変数を複製して、新たに文字列値を保持したいHSTRINGポインタ変数(アドレス変数)を付与する。サンプルでは41行目で使われていて、引数は&hStr2となっています。
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#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");
}
HSTRING hStr1, hStr2;
const wchar_t *cStr1 = L"ワイド文字1";
size_t length = wcslen(cStr1);
length = wcslen(cStr1);
hr = WindowsCreateString(cStr1, length, &hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の生成に成功しました。\n");
}
wprintf_s(L"元文字列 =%s\n", WindowsGetStringRawBuffer(hStr1, nullptr));
wprintf_s(L"hStr1_Address=%p, hStr2_Address=%p\n", hStr1, &hStr2);
hr = WindowsDuplicateString(hStr1, &hStr2);
if (FAILED(hr)) {
wprintf_s(L"文字列の複製に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"文字列の複製に成功しました。\n");
}
wprintf_s(L"参照文字列 =%s\n", WindowsGetStringRawBuffer(hStr2, nullptr));
wprintf_s(L"hStr1_Address=%p, hStr2_Address=%p\n", hStr1, hStr2);
hr = WindowsDeleteString(hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の削除に成功しました。\n");
}
wprintf_s(L"参照文字列 =%s\n", WindowsGetStringRawBuffer(hStr2, nullptr));
wprintf_s(L"hStr1_Address=%p, hStr2_Address=%p\n", hStr1, hStr2);
hr = WindowsDeleteString(hStr2);
if (FAILED(hr)) {
wprintf_s(L"hStr2文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr2文字列の削除に成功しました。\n");
}
RoUninitialize();
_wsystem(L"pause");
return 0;
}
実行結果の出力結果
初期化に成功しました。 hStr1文字列の生成に成功しました。 元文字列 =ワイド文字1 hStr1_Address=00F29C18, hStr2_Address=00EFF930 文字列の複製に成功しました。 参照文字列 =ワイド文字1 hStr1_Address=00F29C18, hStr2_Address=00F29C18 hStr1文字列の削除に成功しました。 参照文字列 =ワイド文字1 hStr1_Address=00F29C18, hStr2_Address=00F29C18 hStr2文字列の削除に成功しました。 続行するには何かキーを押してください . . .
文字列の比較 WindowsCompareStringOrdinal(関数)
2つのHSTRING型文字列同士を比較する関数です。まずは使い方に関する説明とサンプルと動作結果を示します。
- WindowsCompareStringOrdinal(HSTRING型変数,HSTRING型変数,INT32型ポインタ変数);
引数:
- 第1引数:文字列値を比較したいHSTRING文字列変数を付与する。サンプルでは55行目で使われていて、引数はhStr1となっています。
- 第2引数:文字列値を比較したいHSTRING文字列変数を付与する。サンプルでは55行目で使われていて、引数はhStr2となっています。
- 第3引数:第1引数と第2引数で指定した文字列同士を比較して、比較の結果をINT32型のポインタ変数(アドレス変数)を付与する。サンプルでは55行目で使われていて、引数は&INT32CompResultとなっています。第一引数の文字列と第二引数の文字列の比較の結果、現在指定されているLOCALEに基づいた辞書順で1つの目の方が辞書順で小さい場合は-1,同等値(完全一致)なら0,大きい場合は1がポインタの実体値として設定されます。
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#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");
}
HSTRING hStr1, hStr2;
INT32 i32CompResult;
const wchar_t *cStr1 = L"あきたけん";
const wchar_t *cStr2 = L"おおさかふ";
size_t length = wcslen(cStr1);
length = wcslen(cStr1);
hr = WindowsCreateString(cStr1, length, &hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の生成に成功しました。\n");
}
length = wcslen(cStr2);
hr = WindowsCreateString(cStr2, length, &hStr2);
if (FAILED(hr)) {
wprintf_s(L"hStr2文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr2文字列の生成に成功しました。\n");
}
wprintf_s(L"文字列1 =%s\n", WindowsGetStringRawBuffer(hStr1, nullptr));
wprintf_s(L"文字列2 =%s\n", WindowsGetStringRawBuffer(hStr2, nullptr));
wprintf_s(L"hStr1_Address=%p, hStr2_Address=%p\n", hStr1, &hStr2);
hr = WindowsCompareStringOrdinal(hStr1, hStr2, &i32CompResult);
if (FAILED(hr)) {
wprintf_s(L"文字列の比較に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"文字列の比較に成功しました。\n");
}
wprintf_s(L"\n");
wprintf_s(L"比較結果 =%d\n", i32CompResult);
hr = WindowsDeleteString(hStr2);
if (FAILED(hr)) {
wprintf_s(L"hStr2文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr2文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の削除に成功しました。\n");
}
RoUninitialize();
_wsystem(L"pause");
return 0;
}
}
実行結果の出力結果
初期化に成功しました。 hStr1文字列の生成に成功しました。 hStr2文字列の生成に成功しました。 文字列1 =あきたけん 文字列2 =おおさかふ hStr1_Address=0023B778, hStr2_Address=00CFFB60 文字列の比較に成功しました。 比較結果 =-1 hStr2文字列の削除に成功しました。 hStr1文字列の削除に成功しました。 続行するには何かキーを押してください . . .
文字列のNULL値確認 WindowsStringHasEmbeddedNull(関数)
HSTRING型の文字列に\0が埋め込まれているかを確認し、引数のBOOL型アドレス変数の実体にその結果を格納します。1つ以上の\0が含まれていなければTRUEを返します。まずは使い方に関する説明とサンプルと動作結果を示します。
- WindowsStringHasEmbeddedNull(HSTRING型変数,BOOL型アドレス変数);
引数:
- 第1引数:文字列値の\0保持を確認したいHSTRING文字列変数を指定します。サンプルでは55行目で使われていて、引数はhStr1となっています。
- 第2引数:確認結果を受け取る実体のあるBOOL型のアドレス変数を指定します。サンプルでは55行目で使われていて、引数は&B_Resultとなっています。
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#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");
}
HSTRING hStr1, hStr2;
BOOL B_Result;
const wchar_t *cStr1 = L"あきたけん";
wchar_t cStr2[1] = L"";
size_t length = wcslen(cStr1);
length = wcslen(cStr1);
hr = WindowsCreateString(cStr1, length, &hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の生成に成功しました。\n");
}
cStr2[0] = 0x24;//wchar_t型としては不安全な代入(サンプル向けの強行代入)
length = wcslen(cStr2);
hr = WindowsCreateString(cStr2, length, &hStr2);
if (FAILED(hr)) {
wprintf_s(L"hStr2文字列の生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr2文字列の生成に成功しました。\n");
}
wprintf_s(L"文字列1 =%s\n", WindowsGetStringRawBuffer(hStr1, nullptr));
wprintf_s(L"hStr1_Address=%p, hStr2_Address=%p\n", hStr1, &hStr2);
hr = WindowsStringHasEmbeddedNull(hStr1, &B_Result);
if (FAILED(hr)) {
wprintf_s(L"文字列の比較に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"文字列の比較に成功しました。\n");
}
wprintf_s(L"\n");
wprintf_s(L"cStr1\n");
wprintf_s(L"比較結果(B_Result == true) =%d\n", (B_Result == TRUE));
wprintf_s(L"\n");
hr = WindowsStringHasEmbeddedNull(hStr2, &B_Result);
if (FAILED(hr)) {
wprintf_s(L"文字列の比較に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"文字列の比較に成功しました。\n");
}
wprintf_s(L"\n");
wprintf_s(L"cStr2\n");
wprintf_s(L"比較結果(B_Result == true) =%d\n", (B_Result == TRUE));
wprintf_s(L"\n");
hr = WindowsDeleteString(hStr2);
if (FAILED(hr)) {
wprintf_s(L"hStr2文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr2文字列の削除に成功しました。\n");
}
hr = WindowsDeleteString(hStr1);
if (FAILED(hr)) {
wprintf_s(L"hStr1文字列の削除に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"hStr1文字列の削除に成功しました。\n");
}
RoUninitialize();
_wsystem(L"pause");
return 0;
}
実行結果の出力結果
初期化に成功しました。 hStr1文字列の生成に成功しました。 hStr2文字列の生成に成功しました。 文字列1 =あきたけん hStr1_Address=01459DC0, hStr2_Address=0118F938 文字列の比較に成功しました。 cStr1 比較結果(B_Result == true) =0 文字列の比較に成功しました。 cStr2 比較結果(B_Result == true) =1 hStr2文字列の削除に成功しました。 hStr1文字列の削除に成功しました。 続行するには何かキーを押してください . . .
文字列のバッファ確保 WindowsPreallocateStringBuffer(関数)
不変のHSTRING型として文字列を生成する前に、変更可能なPWSTR型文字列変数の文字列領域を確保すると同時に、変更可能な形式のHSTRING_BUFFER型に関連付ける関数です。
- WindowsPreallocateStringBuffer(確保する領域の大きさ,PWSTR型アドレス変数,HSTRING_BUFFER型アドレス変数);
引数:
- 第1引数:確保する文字列変数PWSTRの大きさを指定します。サンプルでは28行目で使われていて、引数は10となっています。
- 第2引数:PWSTR型のアドレス変数を指定します。この変数が文字列バッファとして、HSTRING_BUFFERと連動し、機能します。サンプルでは28行目で使われていて、引数は&PWSTR_Bufferとなっています。
- 第3引数:HSTRING_BUFFER型のアドレス変数を指定します。第二引数の変数と連動するように機能します。サンプルでは28行目で使われていて、引数は&HSTRING_BUFFER_Bufferとなっています。
このWindowsPreallocateStringBufferで連携させたHSTRING_BUFFERをHSTRING型の文字列に引き渡す関数WindowsPromoteStringBufferが42行目で同時にサンプルの中に使われていますが、これについては後述の記事で記述します。
#include <locale.h>
#include <wchar.h>
#include <stdio.h>
#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");
}
HSTRING HSTRING_String = NULL;
HSTRING_BUFFER HSTRING_BUFFER_Buffer = NULL;
PWSTR PWSTR_Buffer = NULL;
hr = WindowsPreallocateStringBuffer(10, &PWSTR_Buffer, &HSTRING_BUFFER_Buffer);
if (FAILED(hr)) {
wprintf_s(L"PWSTRおよびHSTRING_BUFFER文字列(10)の確保に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"PWSTRおよびHSTRING_BUFFER文字列(10)の確保に成功しました。\n");
}
wsprintf(PWSTR_Buffer, L"文字列の出力");
if(SUCCEEDED(hr))
{
hr = WindowsPromoteStringBuffer(HSTRING_BUFFER_Buffer, &HSTRING_String);
if (FAILED(hr)) {
wprintf_s(L"HSTRING_Stringの生成に失敗しました。\n");
_CrtDbgBreak();
return 0;
}
else {
wprintf_s(L"HSTRING_Stringの生成に成功しました。\n");
}
wprintf(L"\n");
wprintf(L"HSTRING_String文字列=%s\n",WindowsGetStringRawBuffer(HSTRING_String, nullptr));
wprintf(L"\n");
}
WindowsDeleteString(HSTRING_String);
RoUninitialize();
_wsystem(L"pause");
return 0;
}
実行結果の出力結果
初期化に成功しました。 PWSTRおよびHSTRING_BUFFER文字列(10)の確保に成功しました。 HSTRING_Stringの生成に成功しました。 HSTRING_String文字列=文字列の出力 続行するには何かキーを押してください . . .
文字列バッファをHSTRING型に引き渡す WindowsPromoteStringBuffer(関数)
バッファ確保のところのサンプルで示しましたが、WindowsPreallocateStringBufferで確保したバッファからHSTRING型の変数に引き渡す関数です。
- WindowsPromoteStringBuffer(HSTRING_BUFFER型変数,実体のあるHSTRING型アドレス変数);
引数:
- 第1引数:文字列値を引き渡したいHSTRING_BUFFER文字列変数を指定する。サンプルでは42行目で使われていて、引数はHSTRING_BUFFER_Bufferとなっています。
- 第1引数:文字列値を受け取るHSTRING型アドレス変数を指定する。サンプルでは42行目で使われていて、引数はHSTRING_Stringとなっています。
このようにして、不変であるHSTRING文字列を使う前に一時的にHSTRING_BUFFERに関連付けた変数と文字列を連携させておいて、最後にHSTRING型で受け取るというような回りくどい方法も準備されてます。どういう風に便利なのかはあんまりわかりません。経験の不足によるものですね。実際にプログラミングをやってみるとコード作成効率があがるコツがわかるんだと思います。つうか、HSTRING型をこの先、利用していく必要があるのかすら謎です。ま、でもHSTRING文字列操作の記事としては完結ですね。
応用:文字列配列のソート std::sortとstd::for_eachの利用
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変数のアドレス変数を保持しなおすような整列であって中身を入れ替えるわけではないので、整列が可能なのです。お間違いなきよういただければと思います。
#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");
}
実行結果
初期化に成功しました。 文字列の生成に成功しました 文字列の削除に成功しました 文字列の生成に成功しました 文字列の削除に成功しました 文字列の生成に成功しました 文字列の削除に成功しました 文字列の生成に成功しました 文字列の削除に成功しました 文字列の生成に成功しました 文字列の削除に成功しました 文字列の生成に成功しました 文字列の削除に成功しました 文字列の生成に成功しました 文字列の削除に成功しました 文字列の生成に成功しました 文字列の削除に成功しました a = 09_文字列置換_置換変数指定,b = 04_文字列ネイティブ変数参照連動 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 04_文字列ネイティブ変数参照連動,b = 09_文字列置換_置換変数指定 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 05_文字列結合,b = 09_文字列置換_置換変数指定 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 05_文字列結合,b = 04_文字列ネイティブ変数参照連動 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 04_文字列ネイティブ変数参照連動,b = 05_文字列結合 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 05_文字列結合,b = 09_文字列置換_置換変数指定 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 深田 恭子,b = 09_文字列置換_置換変数指定 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 09_文字列置換_置換変数指定,b = 深田 恭子 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 小西 真奈美,b = 深田 恭子 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 小西 真奈美,b = 04_文字列ネイティブ変数参照連動 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 04_文字列ネイティブ変数参照連動,b = 小西 真奈美 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 小西 真奈美,b = 05_文字列結合 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 05_文字列結合,b = 小西 真奈美 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 小西 真奈美,b = 09_文字列置換_置換変数指定 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 09_文字列置換_置換変数指定,b = 小西 真奈美 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 小西 真奈美,b = 深田 恭子 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 すず,b = 深田 恭子 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 すず,b = 04_文字列ネイティブ変数参照連動 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 04_文字列ネイティブ変数参照連動,b = 広瀬 すず -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 すず,b = 05_文字列結合 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 05_文字列結合,b = 広瀬 すず -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 すず,b = 09_文字列置換_置換変数指定 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 09_文字列置換_置換変数指定,b = 広瀬 すず -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 すず,b = 小西 真奈美 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 小西 真奈美,b = 広瀬 すず -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 すず,b = 深田 恭子 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 アリス,b = 深田 恭子 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 アリス,b = 04_文字列ネイティブ変数参照連動 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 04_文字列ネイティブ変数参照連動,b = 広瀬 アリス -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 アリス,b = 05_文字列結合 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 05_文字列結合,b = 広瀬 アリス -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 アリス,b = 09_文字列置換_置換変数指定 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 09_文字列置換_置換変数指定,b = 広瀬 アリス -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 アリス,b = 小西 真奈美 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 小西 真奈美,b = 広瀬 アリス -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 アリス,b = 広瀬 すず 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 すず,b = 広瀬 アリス -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 広瀬 アリス,b = 深田 恭子 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 土屋 太鳳,b = 深田 恭子 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 土屋 太鳳,b = 04_文字列ネイティブ変数参照連動 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 04_文字列ネイティブ変数参照連動,b = 土屋 太鳳 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 土屋 太鳳,b = 05_文字列結合 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 05_文字列結合,b = 土屋 太鳳 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 土屋 太鳳,b = 09_文字列置換_置換変数指定 1(>) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 09_文字列置換_置換変数指定,b = 土屋 太鳳 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, a = 土屋 太鳳,b = 小西 真奈美 -1(<) 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 04_文字列ネイティブ変数参照連動,09_文字列置換_置換変数指定,05_文字列結合,深田 恭子,小西 真奈美,広瀬 すず,広瀬 アリス,土 屋 太鳳, 深田 恭子 広瀬 アリス 広瀬 すず 小西 真奈美 土屋 太鳳 09_文字列置換_置換変数指定 05_文字列結合 04_文字列ネイティブ変数参照連動 続行するには何かキーを押してください . . .