C++におけるstrcat関数の使い方5選

C++のstrcat関数を使ったプログラミング例のイメージC++
この記事は約10分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

C++での文字列操作は多岐にわたりますが、その中でも基本的かつ重要な関数の一つがstrcat関数です。

この関数は、二つの文字列を連結する際に使用されます。特に、プログラム内で動的に文字列を結合させたい場合に重宝します。

しかし、使用する際にはいくつか注意すべき点があります。

それについても後述するので、エラーを避けながら効率的にコードを書くための理解を深めていただければと思います。

●strcat関数の基本

strcat関数を用いると、元の文字列(dest)に別の文字列(src)を追加(連結)することができます。

具体的な関数のプロトタイプはこのようになります。

char *strcat(char *dest, const char *src);

この関数は、destの文字列の終端にsrcの文字列を追加し、destの文字列の最後にNULL文字を追加して終端を表します。

重要なのは、destが十分なサイズを持っていることを確認しておく必要がある点です。

さもないと、メモリ領域外への書き込みが発生し、プログラムがクラッシュする原因になります。

○strcat関数とは

この関数は、標準の文字列ライブラリに含まれており、<cstring>または<string.h>ヘッダファイル内で定義されています。

strcat関数は、第一引数として指定された文字列(dest)の末尾に、第二引数として指定された文字列(src)を追加します。

○基本的な使い方のサンプルコード

このサンプルコードは、strcat関数の基本的な使用方法を表しています。

ここでは、二つの文字列を連結して出力する簡単な例を紹介します。

#include <iostream>
#include <cstring>

int main() {
    char str1[20] = "Hello, ";
    char str2[] = "World!";

    // str1にstr2を連結
    strcat(str1, str2);

    std::cout << "連結された文字列: " << str1 << std::endl;

    return 0;
}

このコードを実行すると、「Hello, World!」という文字列が出力されます。

str1の配列サイズはsrcを追加するに足りるサイズが確保されていることを確認してください。

このように、strcat関数を使う際には、バッファのサイズを適切に管理することが重要です。

●strcat関数の詳細な使い方

C++での文字列操作において非常に頻繁に使用されるのが、strcat関数です。

この関数の役割はシンプルですが、正しく効率的に使いこなすためには、いくつかのテクニックが必要です。

ここでは、strcat関数を使った文字列の結合方法について、基本から応用まで詳しく解説します。

○文字列の結合をマスターする

strcat関数を使用する基本的なケースとしては、このような形です。

ここでは、hello という文字列に world を追加しています。

#include <cstring>
char str1[20] = "Hello, ";
char str2[] = "world!";
strcat(str1, str2);
std::cout << str1 << std::endl;  // 出力: Hello, world!

ただ、そうすると配列がオーバーフローする危険性があることを認識しておく必要があります。

安全に使用するためには、結合前に配列のサイズをチェックするか、より安全な関数を使用することが望ましいです。

○サンプルコード1:単純な文字列の結合

サンプルとして、単純な文字列の結合を見てみましょう。

ここでは、strcat 関数を使って二つの文字列を結合し、結果を出力しています。

#include <iostream>
#include <cstring>

int main() {
    char greeting[50] = "Hello, ";
    char name[] = "Alice";
    strcat(greeting, name);
    std::cout << "Greeting message: " << greeting << std::endl; // Greeting message: Hello, Alice
    return 0;
}

このコードのポイントは、greeting 配列が十分なサイズを持っていることを事前に確認している点です。

安全に文字列を結合することができます。

○サンプルコード2:複数の文字列を結合する方法

次に、複数の文字列を一度に結合する例を見てみましょう。

これは、より複雑な文字列操作を行う際に役立ちます。

#include <iostream>
#include <cstring>

int main() {
    char sentence[100] = "Today is ";
    char day[] = "Sunday, ";
    char weather[] = "and it is sunny.";
    strcat(sentence, day);
    strcat(sentence, weather);
    std::cout << "Complete sentence: " << sentence << std::endl;  // Complete sentence: Today is Sunday, and it is sunny.
    return 0;
}

この例では、sentencedayweather を順に追加しています。

それぞれの結合操作が安全に行われるよう、sentence の初期サイズを大きめに設定しています。

●strcat関数の注意点と対処法

strcat関数を利用する際にはバッファオーバーフローのリスクが伴います。

これはdestのバッファがsrc文字列を追加するためのスペースを十分に持っていない場合に発生します。

プログラマーはこのリスクを理解し、適切なチェックを行う必要があります。

また、strcatの代わりにstd::stringクラスの使用や、より安全な関数の適用を検討することが推奨されます。

これで、メモリの安全性が向上し、セキュリティのリスクも低減されます。

○注意すべきポイント

strcat関数を使用する際の最も重要なポイントは、destのバッファがsrc文字列を安全に受け入れられるかどうかを事前に確認することです。

この確認なしにstrcatを使用すると、プログラムが予期せず終了する可能性や、悪意あるコードの注入などセキュリティ上の問題が発生する可能性があります。

外部からの入力を受け取る場合は特に注意が必要で、入力値の検証とサニタイズを徹底することが求められます。

○よくあるエラーとその対処法

strcat関数の使用中に最も一般的に見られるエラーはバッファオーバーフローです。

このエラーを避けるためには、strcatを呼び出す前に必ずdestバッファがsrcを受け入れるための十分な空間を持っているかどうかを確認することが必要です。

より安全なコーディングのためには、文字列の長さを制限するsnprintfやstrncatの使用が推奨されます。

また、関数の返り値やエラーコードをチェックし、問題が見つかった場合には適切なエラーハンドリングを行うことが不可欠です。

これによって、プログラムの安定性が保たれ、意図しない問題の発生を防ぐことができます。

●strcat関数の応用例

strcat関数はその基本的な使い方を超えて、多くの実用的なシナリオで活用することができます。

ここでは、より複雑な文字列操作の応用例として、プログラムにおける動的な文字列生成やファイル名の作成、さらには日付と時間を組み込んだ文字列の作成まで、具体的なサンプルコードを紹介していきます。

実験してみますと、日常的に多用されるこの機能は、プログラムの柔軟性を大きく向上させることができます。

ただ、そうするとプログラムの複雑さが増すため、各処理におけるエラーチェックを忘れずに行う必要があります。

○サンプルコード3:動的な文字列生成

動的な文字列生成の例として、ユーザーからの入力を基にメッセージを作成します。

このサンプルでは、ユーザー名と現在の時間を取得し、それを組み合わせて一つの挨拶文を作り出しています。

#include <iostream>
#include <cstring>
#include <ctime>

int main() {
    char baseStr[50] = "Hello, ";
    char name[50];
    std::cout << "Enter your name: ";
    std::cin.getline(name, 50);

    // 現在の時間を取得
    time_t now = time(0);
    char* dt = ctime(&now);

    // 名前と現在の時刻を組み合わせる
    strcat(baseStr, name);
    strcat(baseStr, ". It is currently ");
    strcat(baseStr, dt);

    std::cout << baseStr << std::endl;

    return 0;
}

このコードは、strcat関数を使用していくつかの異なる文字列を一つの文に結合しています。

動的な要素として現在の時刻を追加することで、より具体的なメッセージを生成しています。

○サンプルコード4:ファイル名の生成

次に、プログラムの出力を保存するためのファイル名を生成する方法を見てみましょう。

ファイル名には実行日時を含めることが一般的です。

これにより、ファイルのバージョン管理が容易になります。

#include <iostream>
#include <cstring>
#include <ctime>

int main() {
    char filename[60] = "output_";
    time_t now = time(0);
    char* dt = ctime(&now);

    // 改行文字を削除
    dt[strlen(dt)-1] = '\0';

    strcat(filename, dt);
    strcat(filename, ".txt");

    std::cout << "Generated filename: " << filename << std::endl;

    return 0;
}

この例では、現在の日時をファイル名に組み込むことで、毎回異なるファイル名を生成しています。

改行文字を削除する処理も重要です、なぜならctime関数は自動的に改行を追加するからです。

○サンプルコード5:日付と時間を組み込んだ文字列の作成

最後に、イベントログやデバッグ情報に使用される日付と時間を含む文字列の生成方法を紹介します。

この技術は、アプリケーションのトラブルシューティングを助けるために役立ちます。

#include <iostream>
#include <cstring>
#include <ctime>

int main() {
    char logEntry[100] = "Log entry at ";
    time_t now = time(0);
    char* dt = ctime(&now);

    // 改行文字を削除
    dt[strlen(dt)-1] = '\0';

    strcat(logEntry, dt);
    strcat(logEntry, ": some events happened.");

    std::cout << logEntry << std::endl;

    return 0;
}

ここでは、ログエントリに対してタイムスタンプを追加することで、いつ何が起こったのかを明確に記録しています。

再び、改行の管理がポイントになります。

まとめ

本記事では、C++のstrcat関数の使い方を基本から応用まで丁寧に解説しました。

strcat関数は便利ですが、適切なバッファサイズ管理を怠るとセキュリティリスクが伴います。

ぜひ、紹介したサンプルコードを実際に試しながら、この関数の正しい使い方をマスターしてください。