munepi.com > Article > stringで前方一致

stringで前方一致

STLのstring型をつかって、前方一致をすることになり、その方法を探りました。

具体的には、コマンドラインツールに引数を与えるときに

-in:hogehoge.bmp

とかやりたくて、-in:まで一致するものを探すということをしたいのです。

まず、思いつくのはstring::compare()。一致しないところで正負の値を返す。

string("-in:hogehoge.bmp").compare("-in:")は、正の値が返るのでよさそうですが(hの部分で)string("-out:hogehoge.bmp").compare("-in:")でも、正の値になってしまいます(oとiを比較)。

前方一致では-in:までは一致しなければいけないので、途中で結果を教えてもらっても困るということになります。

string::find_first_of()は、文字列同士を比較するのではなくて、文字列の中に、文字が含まれているかを探すものだからダメ。つまり、string("-in:hogehoge.bmp").find_first_of("-in:")とかやると、-,i,n,:のいずれかが、-in:hogehoge.bmpに含まれる位置を返すのです。

ようやく見つけたのが、mismatch()。argorithmヘッダーに入っている、汎用関数です。

2つのコンテナを比較して、異なる要素を見つけたらその部分の反復子のペアを返すというもの。

"-in:hogehoge.bmp"と"-in:chomechome.bmp"を比較すると、(h,c)というペアを返すということです。このときに、hが前方一致の最後の文字の直後であれば良いということになります。

stringはコンテナ互換になっていて、iteratorが使えます。そこで、

string prefix("-in:"), arg("-in:hogehoge.bmp");
if ( mismatch(prefix.begin(), prefix.end(), arg.begin()).first == prefix.begin()) ) {
   前方一致の処理...
}

という具合になります。

mismatchへの引数をstringにしておかなくてはいけないのが面倒なのですが、iteratorはchar*であってもいいはずなので、そこは今後の研究課題とします。