C++のgets関数完全ガイド!5つのサンプルコードで学ぶ – Japanシーモア

C++のgets関数完全ガイド!5つのサンプルコードで学ぶ

C++におけるgets関数の詳細ガイドのイメージC++
この記事は約13分で読めます。

 

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

このサービスは複数のSSPによる協力の下、運営されています。

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

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

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

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

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

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

はじめに

この記事では、初心者から上級者までがC++とその重要な機能の一つであるgets関数について理解し、使いこなすための全てを解説します。

プログラミングは奥深く、特にC++はその強力な機能と複雑さで知られていますが、この記事を読むことで、その一端を理解し、実践的な知識を身につけることができます。

●C++とgets関数の基本

C++は、多くのプログラミング言語の中でも特に強力で柔軟性の高い言語です。

オブジェクト指向プログラミングをサポートし、低レベルのメモリ操作も可能なため、高性能なソフトウェア開発に広く用いられています。

C++は、システムプログラミング、ゲーム開発、組み込みシステムなど、幅広い分野で活躍しています。

○C++とは何か?

C++は、C言語を拡張した形で開発されたプログラミング言語で、1983年に登場しました。

オブジェクト指向プログラミングをサポートすることにより、より構造化され、再利用可能なコードを作成することができるようになりました。

また、その性能の高さから、ソフトウェア開発の現場で広く利用されています。

C++は、その複雑さと同時に、高い表現力と効率性を持つ言語として知られています。

○gets関数の基本的な役割

gets関数は、C++(およびC言語)の標準ライブラリに含まれる関数で、ユーザーからの入力を文字列として受け取るために使用されます。

具体的には、標準入力(通常はキーボード)から一行の文字列を読み取り、それをプログラム内の文字列変数に格納する機能を持っています。

しかし、gets関数には重大なセキュリティリスクが存在するため、現代のプログラミングでは使用が推奨されていません。

代わりに、より安全な関数が提供されています。

●gets関数の詳細な使い方

C++におけるgets関数は、文字列の入力を受け取る基本的な方法の一つですが、その使用には細心の注意が必要です。

ここでは、gets関数の標準的な使い方と、その際に生じ得る問題点について詳細に解説していきます。

○サンプルコード1:基本的なgets関数の使用法

gets関数を用いた基本的な例を紹介します。

このコードは、ユーザーからの入力を文字列として受け取り、それを画面に表示する単純なプログラムです。

#include <iostream>
#include <cstdio>

int main() {
    char str[100];
    std::cout << "文字列を入力してください: ";
    gets(str);
    std::cout << "入力された文字列: " << str << std::endl;
    return 0;
}

このプログラムでは、gets関数を使用してユーザーからの入力を配列strに格納しています。

ただし、この方法にはセキュリティ上のリスクが伴うことを覚えておく必要があります。

○サンプルコード2:gets関数を使った入力の取得

次に、少し複雑な例を見てみましょう。

この例では、複数の文字列を入力し、それらを配列に格納する方法を表しています。

#include <iostream>
#include <cstdio>

int main() {
    char str[3][100];
    for (int i = 0; i < 3; ++i) {
        std::cout << "文字列" << i + 1 << "を入力してください: ";
        gets(str[i]);
    }
    for (int i = 0; i < 3; ++i) {
        std::cout << "入力された文字列" << i + 1 << ": " << str[i] << std::endl;
    }
    return 0;
}

このコードでは、3つの異なる文字列を受け取り、それぞれをstr配列の異なる要素に格納しています。

しかし、gets関数の使用は、バッファオーバーフローのリスクを高めるため、推奨されません。

○サンプルコード3:エラーハンドリングとgets関数

gets関数を使用する際は、エラーハンドリングを適切に行うことが重要です。

下記のコードは、入力エラーを検出し、適切に処理する方法を表しています。

#include <iostream>
#include <cstdio>
#include <cstring>

int main() {
    char str[100];
    std::cout << "文字列を入力してください: ";
    if (gets(str) == NULL) {
        std::cerr << "エラー:適切な入力が行われませんでした。" << std::endl;
        return 1;
    }
    std::cout << "入力された文字列: " << str << std::endl;
    return 0;
}

この例では、gets関数がNULLを返した場合、エラーメッセージを出力しプログラムを終了しています。

しかし、gets関数自体が安全でないため、他の入力関数を使用することをお勧めします。

●gets関数の注意点

C++でのgets関数の使用には重要な注意点があります。

特にセキュリティ面での懸念が大きいため、これを理解し、適切な代替手段を採用することが不可欠です。

gets関数は、入力バッファのサイズをチェックせずに文字列を読み込むため、バッファオーバーフローを引き起こす可能性があります。

このバッファオーバーフローは、プログラムの不正な挙動やシステムのセキュリティリスクを招く原因となり得ます。

そのため、現代のC++プログラミングでは、gets関数の使用は避け、より安全な代替関数を利用することが推奨されています。

○gets関数のセキュリティリスクと代替方法

セキュリティリスクを回達するため、gets関数の代わりにfgets関数やstd::getline関数の使用が推奨されます。

これらの関数は、バッファのサイズを超える入力を防ぐことができ、バッファオーバーフローのリスクを軽減します。

また、C++標準ライブラリの一部として提供されるstd::stringクラスとstd::getline関数を組み合わせることで、より安全かつ柔軟に文字列入力を処理できます。

std::stringは動的にサイズが変更されるため、固定サイズのバッファを使用する際によく見られる問題を避けることができます。

○サンプルコード4:安全な代替関数の使用例

安全な文字列入力のための代替方法として、fgets関数とstd::getline関数の使用例を紹介します。

fgets関数を使用した例は下記のようになります。

#include <iostream>
#include <cstdio>

int main() {
    char str[100];
    std::cout << "文字列を入力してください: ";
    fgets(str, sizeof(str), stdin);
    std::cout << "入力された文字列: " << str;
    return 0;
}

このコードでは、fgets関数を使用してユーザー入力を安全に受け取っています。

fgetsはバッファのサイズを指定するため、バッファオーバーフローのリスクを軽減します。

std::getline関数を使用した例は下記のようになります。

#include <iostream>
#include <string>

int main() {
    std::string str;
    std::cout << "文字列を入力してください: ";
    std::getline(std::cin, str);
    std::cout << "入力された文字列: " << str << std::endl;
    return 0;
}

この例では、std::stringクラスとstd::getline関数を使用しています。

これにより、入力される文字列の長さに制限を設けずに安全に処理することが可能です。

●gets関数の応用例

gets関数は、C++プログラミングにおいて基本的な文字列入力の取得手段として知られていますが、実際には様々な応用が可能です。

ただし、先に述べたセキュリティ上のリスクを理解した上で、慎重に使用する必要があります。

ここでは、gets関数を応用した具体的なプログラミングの例をいくつか紹介します。

○サンプルコード5:gets関数を応用した高度な入力処理

例として、gets関数を使用して複数行のテキストを読み込み、その内容を処理するプログラムを考えてみましょう。

下記のコードは、ユーザーが入力した複数行のテキストを配列に格納し、その内容を表示するものです。

#include <iostream>
#include <cstdio>

int main() {
    char text[5][100];
    std::cout << "5行のテキストを入力してください(各行は100文字以下):" << std::endl;

    for (int i = 0; i < 5; ++i) {
        gets(text[i]);
    }

    std::cout << "入力されたテキスト:" << std::endl;
    for (int i = 0; i < 5; ++i) {
        std::cout << text[i] << std::endl;
    }

    return 0;
}

このコードでは、5行のテキストを入力してそれぞれを配列の異なる要素に格納しています。

ただし、このような使い方はバッファオーバーフローのリスクがあるため、実際の開発では避けるべきです。

○gets関数を使用したデータ処理の例

gets関数は、単純なテキスト入力だけでなく、フォーマットされたデータの読み込みにも使うことができます。

例えば、コンマで区切られたデータを読み込んで、それぞれの要素を処理する場合などが考えられます。

下記のコードは、コンマ区切りのデータを読み込んで分割し、それぞれの要素を表示する簡単な例です。

#include <iostream>
#include <cstdio>
#include <cstring>

int main() {
    char line[100];
    std::cout << "コンマ区切りのデータを入力してください:" << std::endl;
    gets(line);

    char* token = strtok(line, ",");
    while (token != NULL) {
        std::cout << token << std::endl;
        token = strtok(NULL, ",");
    }

    return 0;
}

このコードでは、gets関数で読み込んだ行からstrtok関数を使ってコンマで区切られたトークンを抽出しています。

しかし、この方法もgets関数の使用に伴うリスクが存在するため、現実のアプリケーションでは安全な代替手段の採用が望まれます。

●gets関数のカスタマイズ方法

C++のgets関数は、その基本的な使い方に加えて、さまざまな方法でカスタマイズすることが可能です。

ここでは、gets関数の挙動をカスタマイズする方法と、高度な入力処理のためのカスタマイズ例を紹介します。

○gets関数の挙動をカスタマイズする方法

gets関数の基本的な機能は、標準入力からの文字列の読み込みですが、この挙動をカスタマイズすることで、特定の条件に合わせた入力処理を実現できます。

例えば、入力された文字列が特定のフォーマットに従っているかをチェックする機能を追加することが考えられます。

ここでは、入力された文字列が特定のフォーマット(例えば、メールアドレス)に適合しているかをチェックする簡単な例を紹介します。

#include <iostream>
#include <cstdio>
#include <regex>

bool isValidEmailFormat(const char* str) {
    std::regex pattern("[\\w+-.%]+@[\\w.-]+\\.\\w+");
    return std::regex_match(str, pattern);
}

int main() {
    char email[100];
    std::cout << "メールアドレスを入力してください: ";
    gets(email);

    if (isValidEmailFormat(email)) {
        std::cout << "有効なメールアドレスです。" << std::endl;
    } else {
        std::cout << "無効なメールアドレスです。" << std::endl;
    }

    return 0;
}

このコードでは、正規表現を使用してメールアドレスのフォーマットをチェックしています。

gets関数で読み込んだ文字列がこのフォーマットに適合しているかどうかを評価し、結果を出力しています。

○高度な入力処理のカスタマイズ例

gets関数は、単純なテキスト入力だけでなく、より複雑なデータ構造の入力にも応用することが可能です。

例えば、複数行にわたるデータを読み込んで、それぞれを異なる形式で処理するプログラムを作成することができます。

ここでは、複数行の入力を読み込み、それぞれの行を異なる処理で扱うプログラムの例を紹介します。

#include <iostream>
#include <cstdio>

void processLine(const char* line) {
    // ここに各行の処理を記述する
    std::cout << "処理された行: " << line << std::endl;
}

int main() {
    char line[100];
    std::cout << "複数行のテキストを入力してください(終了するにはCtrl+D):" << std::endl;

    while (gets(line)) {
        processLine(line);
    }

    return 0;
}

このプログラムでは、gets関数を使用してユーザーからの複数行の入力を受け取り、各行に対してprocessLine関数を呼び出して処理を行っています。

このように、gets関数を応用することで、様々な形式の入力データを柔軟に扱うことが可能です。

しかし、先に述べたように、gets関数の使用にはセキュリティ上のリスクが伴いますので、実際のアプリケーションでの使用には十分な注意が必要です。

安全な代替手段を探求し、適切に利用することが重要です。

まとめ

この記事では、C++におけるgets関数の基本的な使い方、その注意点、応用例、そしてカスタマイズ方法について詳しく解説しました。

gets関数は便利ですが、セキュリティリスクを伴うため、使用する際には代替の安全な関数を選択することが重要です。

C++プログラミングの深い理解と実践的な知識を身につけることで、より安全で効率的なコードを書くことができるでしょう。