はじめに
C++やC言語で、char
配列で表現されるC言語スタイルの文字列を扱う際、 =
で代入したり +
で連結したりすることはできません。これらの操作には、標準ライブラリ <cstring>
(C言語では <string.h>
)で提供されている専用の関数を使う必要があります。
この記事では、文字列操作の基本である、コピーを行う strcpy()
関数と、連結を行う strcat()
関数の使い方について、注意点と共に解説します。
文字列のコピーと連結のサンプルコード
このコードは、まず strcpy
を使って buffer
配列に最初の文字列をコピーし、次に strcat
を使ってその末尾に別の文字列を連結します。
完成コード
#include <iostream>
#include <cstring> // strcpy, strcat を使うために必要
using namespace std;
int main() {
// 連結後の文字列を格納するのに十分な大きさの配列を準備
char buffer[50];
char part1[] = "今日の天気は";
char part2[] = "晴れです。";
// 1. strcpy (string copy) で最初の文字列をコピー
strcpy(buffer, part1);
cout << "strcpy後: " << buffer << endl;
// 2. strcat (string concatenate) で2番目の文字列を連結
strcat(buffer, part2);
cout << "strcat後: " << buffer << endl;
return 0;
}
実行結果
strcpy後: 今日の天気は
strcat後: 今日の天気は晴れです。
コードの解説
strcpy(コピー先, コピー元)
**str
**ing c
opy
(文字列のコピー)
- 機能: 第2引数(コピー元)の文字列を、第1引数(コピー先)の
char
配列に上書きコピーします。ご提示のコードstrcpy(str0, "str2");
は、その前のstrcpy(str0, "str1");
の内容を完全に上書きしてしまいます。
strcat(連結先, 連結元)
**str
ing concat
**enate(文字列の連結)
- 機能: 第1引数(連結先)の文字列の末尾(終端ヌル文字
\0
の位置)に、第2引数(連結元)の文字列を連結します。
【最重要】バッファオーバーフローの危険性
strcpy
と strcat
を使う上で、最も注意しなければならないのが「バッファオーバーフロー」です。 これらの関数は、コピー先や連結先の配列に、コピーする文字列を格納するための十分な領域があるかどうかをチェックしません。
もし、char buffer[10];
のような小さな配列に、"Hello, World!"
のような長い文字列を strcpy
でコピーしようとすると、配列の境界を越えてメモリが書き換えられてしまい、プログラムのクラッシュや、深刻なセキュリティ上の脆弱性の原因となります。
安全な代替関数: このような危険性を避けるため、書き込む最大文字数を指定できる、より安全なバージョンの関数が用意されています。
strcpy
→strncpy
strcat
→strncat
C++での推奨: 現代のC++プログラミングでは、これらのC言語スタイルの関数が持つリスクを避けるため、メモリ管理を自動で行ってくれる、はるかに安全で高機能な std::string
クラスを使うことが強く推奨されます。
まとめ
今回は、C言語スタイルの文字列を操作するための strcpy
と strcat
関数について解説しました。
strcpy()
: 文字列をコピー(上書き)する。strcat()
: 文字列を末尾に連結する。- 常にバッファオーバーフローの危険性を意識し、コピー先の配列サイズに十分注意する必要がある。
これらの関数はC言語プログラミングの基本ですが、その危険性を理解した上で、strncpy
や std::string
といった、より安全な代替手段を検討することが重要です。