. : tmyk_h : .

何を書くかは決めていません。書きながら方向性が決まってくれば良いと考えています。

C++BuilderXE において文字列から部分文字列を複数回検索する

UnicodeString に格納されている文字列に対して、指定された部分文字列に対するインデックス値を取得する方法として、UnicodeString.Pos メソッドが存在する。

int  __fastcall Pos(const UnicodeString& subStr) const;

System.UnicodeString.Pos - XE API Documentation

しかし、UnicodeString.Pos メソッドには検索を開始するインデックス値を設定する引数が存在しないため、必ず文字列の先頭から検索を開始する形となり、検索したい部分文字列が文字列内に複数箇所存在する場合は最初に出現する部分文字列しか検索する事ができない。

検索を開始インデックス値が指定可能な引数を持つ部分文字列の検索関数として StrUtils パッケージの PosEx 関数が存在しているので、複数回検索したい場合は以下を利用する。

extern PACKAGE int __fastcall PosEx(const System::UnicodeString SubStr, const System::UnicodeString S, int Offset = 0x1)/* overload */;

StrUtils.PosEx - XE API Documentation

実行ファイルが存在していることを前提に、ファイルパスを含む実行ファイル名とプログラム引数の区切り位置を探すために以下の様なコードを書いた。

#include <StrUtils.hpp>
 :

UnicodeString executeCommand = L"C:\\Program Files\\SampleApp\\modules\\SampleApp.exe /param \"parameter\" /a \"\" /u ";
UnicodeString exec;
UnicodeString param = L"";
int pos = 1;
while(1) {
  int idx = PosEx(L" ", executeCommand, pos);
  if (idx == 0) {
    exec = executeCommand;
    break;
  }
  exec = executeCommand.SubString(0, idx);
  if (FileExists(exec.Trim()) == true) {
    param = executeCommand.SubString(idx, executeCommand.Length() - (idx-1));
    break;
  }
  pos = idx+1;
}