大阪市中央区 システムソフトウェア開発会社

営業時間:平日09:15〜18:15
MENU

C++でC風ライブラリを作る(文字列比較編3)

著者:高木信尚
公開日:2019/07/23
最終更新日:2019/07/23
カテゴリー:技術情報

高木です。おはようございます。

文字列比較編も前々回前回に引き続き3回目となりました。
今回で最後です(「C++でC風ライブラリを作る」は続きますよ)。
それでは早速いってみましょう。

前回はstrcmp関数を実装しました。
srcoll関数相当のものは扱わない方針ですので、今回はstrncmp関数相当のものを作ることにします。

まずはナル終端文字列どうしの比較です。

namespace cloverfield
{
  template <typename charT>
  inline int strncmp(charT const* s1, charT const* s2, std::size_t n)
  {
    auto ss1 = s1;
    auto ss2 = s2;

    while (*ss1 && (*ss1 == *ss2))
    {
      ++ss1;
      ++ss2;
      if (ss1 - s1 >= n)
        return 0;
    }
    return *ss1 - *ss2;
  }

  inline int strncmp(char const* s1, char const* s2, std::size_t n)
  {
    return std::strncmp(s1, s2, n);
  }

  inline int strncmp(wchar_t const* s1, wchar_t const* s2, std::size_t n)
  {
    return std::wcsncmp(s1, s2, n);
  }
}

strcmp関数とよく似ていますが、第3引数nが増えた分だけ微妙に異なっています。
また、strcmp関数と同様、char型の文字列についてはstd::strncmp関数を、wchar_t型の文字列についてはstd::wcsncmp関数を使っています。

続いて、比較対象の文字列の一方、または両方がstd::basic_stringの場合について多重定義します。

namespace cloverfield
{
  template <typename charT, typename traits, typename Allocator1, typename Allocator2>
  inline int strncmp(std::basic_string<charT, traits, Allocator1> const& s1, std::basic_string<charT, traits, Allocator2> const& s2, std::size_t n)
  {
    return strncmp(s1.c_str(), s2.c_str(), n);
  }

  template <typename charT, typename traits, typename Allocator>
  inline int strncmp(std::basic_string<charT, traits, Allocator> const& s1, charT const* s2, std::size_t n)
  {
    return strncmp(s1.c_str(), s2, n);
  }

  template <typename charT, typename traits, typename Allocator>
  inline int strncmp(charT const* s1, std::basic_string<charT, traits, Allocator> const& s2, std::size_t n)
  {
    return strncmp(s1, s2.c_str(), n);
  }
}

これも安直な方法で実装しています。

これで文字列比較編は終わりですが、標準Cライブラリにはない大文字・小文字を区別せずに比較するとか、全角・半角を区別せずに比較するとか、ひがらな・カタカナを区別せずに比較するとかのstrcoll関数とはまた違った形で一種の辞書順比較を行う関数もそのうち作りたいと思います。

    上に戻る