C++ プログラミング:文字列操作の定番 std::basic_string::copy を徹底解説


std::basic_string::copy 関数は、std::basic_string オブジェクトのサブ文字列を別の文字列オブジェクトまたは C スタイルの文字列配列にコピーするために使用されます。この関数は、文字列の複製、部分文字列の抽出、文字列のフォーマットなど、さまざまな目的に使用できます。

構文

size_type copy(char_t* dest, size_type npos = npos, size_type pos = 0) const;

パラメータ

  • pos: コピーを開始する位置。デフォルトは 0 (先頭)
  • npos: コピーする文字数の最大値。デフォルトは npos (最大長)
  • dest: コピー先の文字列オブジェクトまたは C スタイルの文字列配列へのポインタ

戻り値

実際にコピーされた文字数

詳細

  • nposcount に指定すると、ソース文字列全体がコピーされます。
  • possize() より大きい場合は、std::out_of_range 例外がスローされます。
  • コピーされた文字列は、dest でヌル文字で終端されません。
  • std::basic_string::copy 関数は、ソース文字列の pos 番目の文字から始まり、npos または size() - pos のいずれか少ない文字を dest にコピーします。

std::string str = "Hello, World!";

// 文字列全体を C スタイルの文字列配列にコピー
char buffer[14];
str.copy(buffer);
std::cout << buffer << std::endl; // 出力: Hello, World!

// 部分文字列を別の std::string オブジェクトにコピー
std::string subStr = str.copy(3, 5);
std::cout << subStr << std::endl; // 出力: llo

// 文字列の先頭 5 文字を逆順にコピー
char reversed[6];
for (int i = 0; i < 5; ++i) {
  reversed[i] = str[4 - i];
}
reversed[5] = '\0';
std::cout << reversed << std::endl; // 出力: olleH
  • ターゲットの文字列オブジェクトが十分な大きさでない場合、バッファオーバーフローが発生する可能性があります。
  • std::basic_string::copy 関数は、ソースとターゲットの文字列オブジェクトが同じである場合、動作が未定義になります。
  • 上記の例は、std::basic_string::copy 関数の基本的な使用方法を示しています。より複雑な操作には、この関数の他の機能を組み合わせて使用することができます。
  • この関数は、さまざまな文字列処理タスクに使用できる汎用的なツールです。
  • std::basic_string::copy 関数は、効率的な文字列操作を提供するために、C++ 標準ライブラリで提供されています。


文字列全体をコピー

#include <iostream>
#include <string>

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

  // 文字列全体を別の std::string オブジェクトにコピー
  std::string copyStr = str.copy();
  std::cout << "コピーされた文字列: " << copyStr << std::endl;

  // 文字列全体を C スタイルの文字列配列にコピー
  char buffer[14];
  str.copy(buffer);
  std::cout << "C スタイルの文字列配列: " << buffer << std::endl;

  return 0;
}

出力

コピーされた文字列: Hello, World!
C スタイルの文字列配列: Hello, World!

部分文字列をコピー

#include <iostream>
#include <string>

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

  // 文字列の先頭 5 文字を別の std::string オブジェクトにコピー
  std::string subStr = str.copy(0, 5);
  std::cout << "先頭 5 文字: " << subStr << std::endl;

  // 文字列の最後の 5 文字を C スタイルの文字列配列にコピー
  char buffer[6];
  str.copy(str.size() - 5, 5, buffer);
  buffer[5] = '\0';
  std::cout << "最後の 5 文字: " << buffer << std::endl;

  return 0;
}

出力

先頭 5 文字: Hello
最後の 5 文字: World

文字列を逆順にコピー

#include <iostream>
#include <string>

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

  // 文字列を逆順に別の std::string オブジェクトにコピー
  std::string reversedStr;
  for (int i = str.size() - 1; i >= 0; --i) {
    reversedStr += str[i];
  }
  std::cout << "逆順の文字列: " << reversedStr << std::endl;

  // 文字列を逆順に C スタイルの文字列配列にコピー
  char buffer[str.size() + 1];
  for (int i = 0, j = str.size() - 1; i < str.size(); ++i, --j) {
    buffer[i] = str[j];
  }
  buffer[str.size()] = '\0';
  std::cout << "逆順の C スタイル文字列: " << buffer << std::endl;

  return 0;
}

出力

逆順の文字列: !dlroW ,olleH
逆順の C スタイル文字列: !dlroW ,olleH


代入演算子

最も単純な方法は、代入演算子を使用して文字列をコピーすることです。

std::string str1 = "Hello, World!";
std::string str2;

str2 = str1; // str2 に str1 の内容をコピー

コンストラクタ

文字列リテラルまたは別の文字列オブジェクトを使用して、新しい std::string オブジェクトを作成することもできます。

std::string str1 = "Hello, World!";
std::string str2(str1); // str2 に str1 の内容をコピー

// または
std::string str3 = str1; // str3 に str1 の内容をコピー

アルゴリズム

C++ 標準ライブラリには、std::copy アルゴリズムなど、文字列をコピーするためのアルゴリズムがいくつか用意されています。

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

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

  std::copy(str1.begin(), str1.end(), std::back_inserter(str2)); // str2 に str1 の内容をコピー
  std::cout << str2 << std::endl;

  return 0;
}

イテレータ

ループを使用して、文字列の各文字を手動でコピーすることもできます。

std::string str1 = "Hello, World!";
std::string str2;

for (char c : str1) {
  str2 += c;
}

std::cout << str2 << std::endl;

サブ文字列

std::string::substr 関数を使用して、文字列の一部をコピーすることもできます。

std::string str1 = "Hello, World!";
std::string str2 = str1.substr(7, 5); // str2 に "World" をコピー

std::cout << str2 << std::endl;

最適な方法の選択

使用する方法は、状況によって異なります。一般的に、以下の場合は std::basic_string::copy 関数を使用するのが効率的です。

  • 頻繁にコピー操作を行う場合
  • 短い文字列をコピーする場合

以下の場合は、他の方法を使用する方が効率的である場合があります。

  • 柔軟性の高い制御が必要な場合
  • 特定の部分文字列のみをコピーする場合
  • 長い文字列をコピーする場合