【初心者向け】C++の`Strings`操作:`std::toupper` で英字を大文字に変換


  • 戻り値:
    • 変換後の大文字 (変換できない場合は入力文字と同じ)
  • 引数:
    • ch: 変換対象の文字
    • loc: ロケールオブジェクト (省略可。省略時はデフォルトロケールを使用)
  • 関数プロトタイプ:
    template<class charT, class traits>
    charT toupper(charT ch, const locale& loc = std::locale());
    
  • ヘッダーファイル: <locale>

std::toupper の動作

std::toupper は、ロケールによって定義された文字変換規則に基づいて、英字を大文字に変換します。デフォルトロケールでは、ASCII 文字セットの英字 (a から z) を A から Z に変換します。

例:

char ch = 'a';
char upperChar = std::toupper(ch);  // upperChar は 'A' になります

std::toupper の使用方法

std::toupper は、個々の文字を変換したり、文字列全体を変換したりするために使用できます。

個々の文字を変換

char ch = 'h';
char upperChar = std::toupper(ch);
std::cout << upperChar << std::endl;  // H が出力されます

文字列全体を変換

std::string str = "hello, world";
std::transform(str.begin(), str.end(), std::back_inserter(upperStr), std::toupper);
std::cout << upperStr << std::endl;  // HELLO, WORLD が出力されます

std::locale を使用してロケールを指定

std::locale loc(std::locale("ja_JP.UTF-8"));
char ch = 'あ';
char upperChar = std::toupper(ch, loc);  // upperChar は 'ア' になります (日本語ロケールの場合)
  • std::toupper は、文字列を直接変更するのではなく、変換後の文字を新しい文字列に格納する必要があります。
  • ロケールによっては、英字以外の文字も大文字に変換される場合があります。
  • std::toupper は、英字のみを大文字に変換します。数字や記号などの他の文字は変換されません。

std::toupper は、C++ の Strings 操作において、文字列中の英字を大文字に変換するために非常に便利な関数です。個々の文字を変換したり、文字列全体を変換したり、ロケールを指定して変換したりと、様々な用途に使用できます。

  • C++11 以降では、std::algorithm ヘッダーに std::transform アルゴリズムが導入され、std::toupper を用いた文字列変換をより簡潔に記述することができます。
  • std::toupper は、C 言語の toupper 関数と同様の機能を提供します。


個々の文字を変換

#include <iostream>
#include <locale>

int main() {
  char ch = 'h';
  char upperChar = std::toupper(ch);
  std::cout << "小文字: " << ch << std::endl;
  std::cout << "大文字: " << upperChar << std::endl;

  return 0;
}

文字列全体を変換

#include <iostream>
#include <algorithm>
#include <locale>
#include <string>

int main() {
  std::string str = "hello, world";
  std::string upperStr;

  std::transform(str.begin(), str.end(), std::back_inserter(upperStr), std::toupper);

  std::cout << "元の文字列: " << str << std::endl;
  std::cout << "変換後: " << upperStr << std::endl;

  return 0;
}

このコードは、"hello, world" という文字列を std::transform アルゴリズムと std::toupper を使ってすべて大文字に変換し、変換前後の文字列を出力します。

#include <iostream>
#include <locale>
#include <string>

int main() {
  std::locale loc(std::locale("ja_JP.UTF-8"));
  std::string str = "こんにちは";
  std::string upperStr;

  std::transform(str.begin(), str.end(), std::back_inserter(upperStr),
                 std::toupper(std::use_facet<std::ctype<char>>(loc)));

  std::cout << "元の文字列: " << str << std::endl;
  std::cout << "変換後: " << upperStr << std::endl;

  return 0;
}


手動で大文字に変換する

最も単純な方法は、英字の大小文字の対応関係を把握し、手動で変換することです。例えば、以下のようなコードで 'a''A' に変換できます。

char ch = 'a';
ch -= 'a' - 'A';  // 'a' と 'A' の ASCII コードの差分を引く
std::cout << ch << std::endl;  // 'A' が出力されます

この方法は、簡単な文字列変換であれば有効ですが、複雑な文字列や、さまざまなロケールでの変換に対応するには不向きです。

std::tolower と組み合わせて使用する

std::toupperstd::tolower を組み合わせることで、大文字と小文字を相互に変換することができます。例えば、以下のようなコードで 'a''A' に変換できます。

char ch = 'a';
ch = std::isupper(ch) ? std::tolower(ch) : std::toupper(ch);
std::cout << ch << std::endl;  // 'A' が出力されます

この方法は、大文字・小文字のどちらに変換するかを判定してから変換を行うので、柔軟性があります。ただし、std::isupperstd::tolower の呼び出しが必要になるため、若干コードが冗長になります。

std::ctype クラスを使用する

std::ctype クラスは、文字種や文字変換に関する情報を提供するクラスです。このクラスを利用することで、ロケールに依存した大文字変換を行うことができます。

#include <iostream>
#include <locale>

int main() {
  std::locale loc(std::locale("ja_JP.UTF-8"));
  std::string str = "こんにちは";

  for (char ch : str) {
    std::cout << std::use_facet<std::ctype<char>>(loc).toupper(ch);
  }

  return 0;
}

この方法は、ロケールに依存した変換が必要な場合に有効です。ただし、std::ctype クラスの操作は若干複雑になるため、ある程度の知識が必要です。

Boost.C++ ライブラリを使用する

Boost.C++ ライブラリには、to_upper という関数テンプレートが提供されています。この関数は、std::toupper と同様の機能を提供しますが、より汎用性が高く、エラー処理などの機能も備えています。

#include <boost/algorithm/string/case.hpp>

int main() {
  std::string str = "hello, world";
  boost::algorithm::to_upper(str);
  std::cout << str << std::endl;  // HELLO, WORLD が出力されます
}

この方法は、Boost.C++ ライブラリを導入する必要があるという点に注意が必要です。

上記以外にも、独自の文字列操作ライブラリを提供しているものがあります。例えば、PCL や Eigen などのライブラリには、大文字変換を含む文字列操作関数などが提供されている場合があります。

適切な方法を選択する

どの方法を選択するかは、状況によって異なります。

  • 特定のライブラリとの連携: そのライブラリが提供する関数を使用する
  • 汎用性の高い変換: Boost.C++ ライブラリを使用する
  • ロケール依存の変換: std::ctype クラスを使用する
  • 柔軟性が必要: std::tolower と組み合わせて使用する
  • シンプルな変換: 手動による変換