見出し画像

2024-07-03C++プログラミング練習


こんにちわ。ケロッグです。今日も今日とてC++プログラミング練習をChatGPTと一緒にやっていきます。
いつもと同じようにGPTに問題を出してもらって、プログラムを書いて、フィードバックをもらいます。今日はフィードバックをもらってさらにプログラムを書き直しました。

GPTとのやり取り

今日の学び


今日の学びを先に書いてしまいます。今日、主に学んだことは以下の2点です。
・ポインタ渡しと参照渡しの違い
・参照型への型推論

ポインタ渡しと参照渡しの違い

値渡しとそれ以外については、違いを理解できていましたが、今回プログラムを書くときに、ポインタ渡しをしようか参照渡しをしようか学びました。この2つ、何が違うねんと思って迷ってしまいました。詳しい解説は他の記事に譲るとして、今回私の中で言語化したものを残しておきます。

ポインタ渡し

変数のメモリ上のアドレスを渡す。
・NULLチェックが必要。

参照渡し

元の変数に別名をつける。
NULLがない。→呼び出し元で、NULLでないことをプログラムに文法レベルで要求される。

つまり、主な違いはNULLがあるかないか。参照渡しはNULLがないことで簡易的に渡すことができるが、渡しているものがNULLではないことをしっかり保証してあげる必要がある。

参照型への型推論

下は今回書いたプログラムの一部です。
Transactionクラスのベクター型にtransactionsベクターを定義しています。そして、範囲for文の中で型推論を行い、auto& transactionはTransaction&と推論されていることがわかります。これは教科書いわく良く使う書き方らしいので、しっかり覚えておきたいです。

class HouseholdAccount {
private:
    std::vector<Transaction> transactions;

public:
    void addTransaction(const Transaction& transaction) {
        transactions.push_back(transaction);
    }

    void printMonthlyReport() {
        std::map<std::string, int> monthlyBalance;

        for (const auto& transaction : transactions) {
            // 型推論を使用
            const auto& date = transaction.getDate();
            std::string month = date.substr(0, 7); // YYYY-MM 部分を抽出

            monthlyBalance[month] += transaction.getAmount();
        }


今回作った成果物

最後に今回作った成果物を載せておきます。
簡易的な家計簿アプリを作りました。いちいちコマンド上で入力しなくてはいけないので、使い物になりませんが、これを応用してCSVなどからデータをインプットする仕様にすれば、使い道はあるかなあと思いました。

 #include  <iostream> #include  <string> #include  <vector> #include  <sstream> #include  <iomanip> // for std::setw

class Transaction {
private:
    std::string Category;
    int Money;
    std::string Day;

public:
    Transaction(const std::string& category, int money, const std::string& day)
        : Category(category), Money(money), Day(day) {}

    std::string getCategory() const { return Category; }
    int getMoney() const { return Money; }
    std::string getDay() const { return Day; }
};

class HouseholdAccount {
private:
    std::vector<Transaction> transactions;

public:
    void addTransaction(const Transaction& transaction) {
        transactions.push_back(transaction);
    }

    void printMonthlyReport() const {
        std::cout << "月間レポート" << std::endl;
        if (transactions.empty()) {
            std::cout << "取引がありません。" << std::endl;
            return;
        }
        int sumIncome = 0;
        int sumExpense = 0;

        std::cout << std::setw(12) << "日付" << std::setw(12) << "金額" << std::setw(20) << "カテゴリー" << std::endl;
        std::cout << "----------------------------------------" << std::endl;
        for (const auto& transaction : transactions) {
            std::cout << std::setw(12) << transaction.getDay() << std::setw(12) << transaction.getMoney() << std::setw(20) << transaction.getCategory() << std::endl;
            if (transaction.getMoney() >= 0) {
                sumIncome += transaction.getMoney();
            } else {
                sumExpense += transaction.getMoney();
            }
        }
        std::cout << "----------------------------------------" << std::endl;
        std::cout << std::setw(12) << "合計収入:" << std::setw(12) << sumIncome << std::endl;
        std::cout << std::setw(12) << "合計支出:" << std::setw(12) << sumExpense << std::endl;
        std::cout << std::setw(12) << "純収支:" << std::setw(12) << sumIncome + sumExpense << std::endl;
    }
};

int main() {
    HouseholdAccount acc;
    std::string day;
    std::string moneyStr;
    std::string category;

    while (true) {
        std::cout << "取引の日付を入力してください (例: 2024-07-03): ";
        std::getline(std::cin, day);

        if (day.empty()) {
            break;
        }

        std::cout << "金額を入力してください: ";
        std::getline(std::cin, moneyStr);

        std::istringstream moneyStream(moneyStr);
        int money;
        if (!(moneyStream >> money)) {
            std::cout << "無効な金額です。再度入力してください。" << std::endl;
            continue;
        }

        std::cout << "カテゴリーを入力してください: ";
        std::getline(std::cin, category);

        Transaction tra(category, money, day);
        acc.addTransaction(tra);
    }

    acc.printMonthlyReport();

    return 0;
}

出力

今日は以上です。どうもありがとうございました。

この記事が気に入ったらサポートをしてみませんか?