まず、Kakeiboクラスのコンストラクタが よばれると、常に残金を0にしてしまうのを防ぎましょう。
#include <iostream.h> #include <fstream.h> #include <stdlib.h> class Kakeibo { int zankin; public: Kakeibo(); void Input(int); void Output(int); void Disp(void); int GetZankin(void); void SetZankin(void); }; Kakeibo::Kakeibo(void) { zankin = GetZankin(); } void Kakeibo::Input(int mon) { zankin += mon; return; } void Kakeibo::Output(int mon) { zankin -= mon; return; } void Kakeibo::Disp(void) { cout << "残金は" << zankin << "円です" << endl; return; } int Kakeibo::GetZankin(void) { char c, zan[6]; int i = 0; ifstream KakeiFile("kakei.dat"); while (KakeiFile.get(c)) { zan[i++] = c; } zan[i] = '\0'; if (zan[0] == '\0') return 0; return (atoi(zan)); } void Kakeibo::SetZankin(void) { ofstream KakeiFile("kakei.dat", ios::trunc); KakeiFile << zankin; return; } int main(void) { char sw; int okane; cout << "家計簿" << endl; cout << "I:収入 O:支出 D:残金表示 E:終了" << endl; Kakeibo Mykakei; while(1) { cout << "何をしますか="; cin >> sw; switch(sw) { case 'I':cout << "収入金額="; cin >> okane; Mykakei.Input(okane); break; case 'O':cout << "支出金額="; cin >> okane; Mykakei.Output(okane); break; case 'D':Mykakei.Disp(); break; case 'E':cout << "終了します" << endl; Mykakei.SetZankin(); goto End; break; default:cout << "もう一度入力して下さい" << endl; break; } } End: return 0; }
上のプログラムを少し解説しましょう。
一番わかりにくいのが、メンバ関数の GetZankin関数ではないでしょうか。 これは、まずKakeiFileオブジェクトを "kakei.dat"を開いて生成されます。 もし、"kakei.dat"ファイルが存在しないときは この名前のファイルを作ります。この時ファイルの中身は ありません。 次に、このファイルの中身を一字ずつ読み出して、 zan[]に書き込みます。 最後にヌル文字を付け加えます。 ファイルが空であった場合、zan[0]は'\0'になるので 0を返します。そうでない場合は、読み込んだ 文字列をint型に直して返します。 これで、コンストラクタが呼ばれると自動的に 前回の残金がセットされますね。全くの初回の時は 0がセットされます。
このプログラムが終了時には SetZankinが呼ばれます。 この関数の中身を少し説明します。 多分、ios::truncというのがわからない のではないでしょうか。 これは、前回の記録を消して新たに書き加えなさい という意味です。 終了時に、前回の記録の後ろに記録を追加していっては 困りますからね。
ま、こんなところで今回のプログラムの説明はよいでしょう。
これは、見た目は前回作ったものと同じですね。
全くの初回では、残金が0になっています。
収入と支出を行って、最終的に残金は4900円となりました。
はい、2回目の起動です。残金を表示させると
ちゃんと4900円になっていますね。
すこし、本物の家計簿らしくなってきましたね。
Update Feb/21/1997 By Y.Kumei