【保存版】C++のstd::basic_string::atを使いこなしてコードをもっとスマートに


std::basic_string::at は、C++標準ライブラリが提供する std::basic_string クラスのメンバー関数の一つで、指定された位置の文字への参照を返すものです。文字列中の特定の文字にアクセスしたり、修正したりする際に用いられます。

関数シグネチャ

reference at(size_type pos);
const_reference at(size_type pos) const;

引数

  • pos: 文字列中の位置を表す非負の整数値。最初の文字は位置 0 とみなされます。

戻り値

  • 参照型 reference または const_reference:
    • std::basic_string オブジェクトが const 修飾されていない場合は、reference 型の参照を返します。これは、参照された文字を変更することを許可します。
    • std::basic_string オブジェクトが const 修飾されている場合は、const_reference 型の参照を返します。これは、参照された文字の読み取りのみを許可します。

例外

  • pos が文字列の長さよりも大きい場合、std::out_of_range 例外がスローされます。

使い方

以下の例では、std::basic_string::at を使って文字列中の特定の文字にアクセスし、修正する方法を示します。

#include <iostream>
#include <string>

int main() {
  std::string str = "Hello, World!";

  // 文字列の 7 番目の文字を取得 (これは 'o' です)
  char ch = str.at(7);
  std::cout << ch << std::endl; // 'o' を出力

  // 文字列の 5 番目の文字を 'y' に変更
  str.at(5) = 'y';
  std::cout << str << std::endl; // "Hely, World!" を出力

  return 0;
}
  • 多くの場合、パフォーマンスと安全性において std::basic_string::at の方が std::basic_string::operator[] よりも優れています。
  • std::basic_string::at は、std::basic_string::operator[] と似ていますが、以下の点が異なります。
    • std::basic_string::at は、例外を使用して無効なインデックスを処理します。一方、std::basic_string::operator[] は、無効なインデックスの場合に未定義の動作を引き起こす可能性があります。
    • std::basic_string::at は、参照を返すため、参照された文字を変更することができます。一方、std::basic_string::operator[] は、値を返すため、参照された文字を変更することはできません。


文字列中の特定の文字にアクセスする

#include <iostream>
#include <string>

int main() {
  std::string str = "Hello, World!";

  // 文字列の 7 番目の文字を取得 (これは 'o' です)
  char ch = str.at(7);
  std::cout << ch << std::endl; // 'o' を出力

  return 0;
}

文字列の特定の位置に文字を挿入する

#include <iostream>
#include <string>

int main() {
  std::string str = "Goodbye";

  // 文字列の 3 番目の文字の後に 'World' を挿入
  str.at(3) = ' ';
  str.insert(str.at(3), "World");

  std::cout << str << std::endl; // "Good Worldbye" を出力

  return 0;
}

文字列中の特定の文字を削除する

#include <iostream>
#include <string>

int main() {
  std::string str = "Hello, World!";

  // 文字列の 7 番目の文字を削除 (これは 'o' です)
  str.erase(str.at(7));

  std::cout << str << std::endl; // "Hello, Wrd!" を出力

  return 0;
}

文字列中の部分文字列を置き換える

#include <iostream>
#include <string>

int main() {
  std::string str = "Hello, World!";

  // 文字列 "World" を "Universe" に置き換える
  str.replace(str.find("World"), 5, "Universe");

  std::cout << str << std::endl; // "Hello, Universe!" を出力

  return 0;
}

これらの例は、std::basic_string::at を使って様々な文字列操作を行う方法を示すほんの一例です。この関数は、文字列を操作する際に柔軟で強力なツールを提供します。

上記の例では、std::basic_string::at を使って文字列にアクセス、挿入、削除、置換する方法を示しました。これらの操作は、他の std::basic_string メンバー関数と組み合わせて使用することができます。

例えば、std::basic_string::find メンバー関数を使って、置き換えるべき部分文字列の位置を見つけることができます。

std::string str = "Hello, World!";
size_t pos = str.find("World");
if (pos != std::string::npos) {
  str.replace(pos, 5, "Universe");
}


std::basic_string::operator[] を使用する

std::basic_string::operator[] は、インデックスを使って文字列中の文字にアクセスするもう 1 つの方法です。std::basic_string::at と似ていますが、以下の点が異なります。

  • std::basic_string::operator[] は、値を返すため、参照された文字を変更することはできません。
  • std::basic_string::operator[] は、例外をスローせずに無効なインデックスを処理します。代わりに、未定義の動作を引き起こす可能性があります。

以下のコード例は、std::basic_string::operator[] を使って文字列の 7 番目の文字を取得する方法を示しています。

#include <iostream>
#include <string>

int main() {
  std::string str = "Hello, World!";

  // 文字列の 7 番目の文字を取得 (これは 'o' です)
  char ch = str[7];
  std::cout << ch << std::endl; // 'o' を出力

  return 0;
}

イテレータを使用する

std::basic_string イテレータを使用して、文字列内の各要素を反復処理することができます。これは、文字列中の特定の文字にアクセスしたり、修正したりする場合に役立ちます。

#include <iostream>
#include <string>

int main() {
  std::string str = "Hello, World!";

  // 文字列の 7 番目の文字を取得 (これは 'o' です)
  auto it = str.begin() + 7;
  char ch = *it;
  std::cout << ch << std::endl; // 'o' を出力

  return 0;
}

範囲ベース for ループを使用する

範囲ベース for ループを使用して、std::basic_string の各文字を反復処理することもできます。これは、文字列中のすべての文字にアクセスしたり、処理したりする場合に役立ちます。

以下のコード例は、範囲ベース for ループを使って文字列の各文字を出力する方法を示しています。

#include <iostream>
#include <string>

int main() {
  std::string str = "Hello, World!";

  for (char ch : str) {
    std::cout << ch << " ";
  }
  std::cout << std::endl;

  return 0;
}

アルゴリズムを使用する

std::basic_string には、文字列を操作するための様々なアルゴリズムが用意されています。これらのアルゴリズムを使用して、特定の文字を検索したり、置換したり、削除したりすることができます。

以下のコード例は、std::find アルゴリズムを使って文字列の中に "World" が存在するかどうかを確認する方法を示しています。

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

int main() {
  std::string str = "Hello, World!";

  auto it = std::find(str.begin(), str.end(), 'W');
  if (it != str.end()) {
    std::cout << "文字列の中に 'World' が含まれています。" << std::endl;
  } else {
    std::cout << "文字列の中に 'World' が含まれていません。" << std::endl;
  }

  return 0;
}

いつどの代替方法を使用すべきか

使用する代替方法は、状況によって異なります。

  • 特定の文字列操作が必要な場合
    アルゴリズムを使用します。
  • 文字列全体を反復処理する必要がある場合
    イテレータまたは範囲ベース for ループを使用します。
  • 例外処理が必要な場合
    std::basic_string::at を使用します。
  • シンプルで高速なアクセスが必要な場合
    std::basic_string::at または std::basic_string::operator[] を使用します。