C++ で文字列を小文字に変換する方法

胡金庫 2023年12月11日
C++ で文字列を小文字に変換する方法

この記事では、C++ で文字列を小文字に変換する方法を紹介します。

C++ で文字列変換を行う前に最初に自問するのは、入力文字列のエンコーディングの種類です。マルチバイトのエンコーディング文字で std::lower を使用すると、バグのあるコードが確実に得られるためです。

以下の関数は std::string の小文字変換をきちんと実装しているように見えても、エンコーディングが UTF-8 であるため、すべての文字を小文字に変換しているわけではありません。

#include <algorithm>
#include <iostream>

std::string toLower(std::string s) {
  std::transform(s.begin(), s.end(), s.begin(),
                 [](unsigned char c) { return std::tolower(c); });
  return s;
}

int main() {
  std::string string1 = u8"ÅSH to LoWer WÅN";
  std::cout << "input string:  " << string1 << std::endl
            << "output string: " << toLower(string1) << std::endl;
  return 0;
}

上記のコードは ASCII 文字列やその他の非 ASCII 文字列に対しては問題なく動作しますが、ラテン文字を含むような少し変わった入力を与えると、出力は満足のいくものではありません。

出力:

input string:  ÅSH to LoWer WÅN
output string: Åsh to lower wÅn

これは、Å 記号を å に下げるべきだったので、正しくありません。では、この問題を解決して正しい出力を得るにはどうすればよいのでしょうか?

この問題を解決する最良の移植性のある方法は、ICU (International Components for Unicode) ライブラリを使用することです。

ソースファイルには以下のヘッダを含めるだけです。これらのライブラリは、あなたのプラットフォームに既に含まれていて利用可能な可能性が高いので、コードサンプルは問題なく動作するはずです。しかし、IDE/コンパイル時のエラーが発生した場合は、ICU documentation website にあるライブラリのダウンロード方法を参照してください。

#include <unicode/locid.h>
#include <unicode/unistr.h>
#include <unicode/ustream.h>

これでヘッダが含まれるようになったので、以下のように std::string を小文字に変換するコードを書くことができるようになりました。

#include <unicode/locid.h>
#include <unicode/unistr.h>
#include <unicode/ustream.h>

#include <iostream>

int main() {
  std::string string1 = u8"ÅSH to LoWer WÅN";
  icu::UnicodeString unicodeString(string1.c_str());
  std::cout << "input string:  " << string1 << std::endl
            << "output string: " << unicodeString.toLower() << std::endl;
  return 0;
}

なお、このコードをコンパイルする際には、ICU ライブラリの依存関係を含めるために、以下のコンパイラフラグをつけてコンパイルする必要があります。

g++ sample_code.cpp -licuio -licuuc -o sample_code

コードを実行すると、期待通りの正しい出力が得られます。

input string:  ÅSH to LoWer WÅN
output string: åsh to lower wån

まったく同じ関数で、通常ユーザー入力として予期しないいくつかの異なる言語を処理できます。また、toLower 関数のパラメーターとしてロケールを明示的に指定することもできます。

#include <iostream>
#include <unicode/unistr.h>
#include <unicode/ustream.h>
#include <unicode/locid.h>

int main() {
    std::string string2 = "Κάδμῳ ἀπιϰόμενοι.. Ελληνας ϰαὶ δὴ ϰαὶ γράμματα, οὐϰ ἐόντα πρὶν Ελλησι";
    icu::UnicodeString unicodeString2(string2.c_str());
    std::cout  << unicodeString2.toLower("el_GR") << std::endl;
    return 0;
}
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ String