カレンダー(ファイルオープンによるメモ機能付き)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
YOU's

カレンダー(ファイルオープンによるメモ機能付き)

#1

投稿記事 by YOU's » 14年前

はじめましてYOU'sと申します。
まだ初心者の私です。
ちょっと困っておりまして、皆様の知恵を貸していただきたいと思います。

西暦、月を入力したら、カレンダーが表示され。

日付を入力すると、その日にちにメモが書き込め。

*でその日はメモを書いたとわかる。
また、読み込みでそのメモが開ける。

この時のファイルの入出力は主にtxtファイル。

そして、入力して失敗などして入力しても、一回一回前に戻ることもでき、指定のキーを押すと途中終了もできる。
私のだと「b」で戻る、「g」次へ、「c」でカレンダのチェック、「x」でプログラムの強制終了。

とくにこれから先のファイルRead、Writeの部分をどうコーディングすればいいのかわかりません。

また、一回一回の入力ごとに前に戻れたり指定のキーで終了も、どのようにすればいいのか・・・

今現在の進行状況として西暦と月の入力部分だけです。
西暦と月も関数化して分けたほうがいいのでしょうか?

コード:

int main(void)
{
	int year,month;
	char i,n=0,str[256];

	printf("* * * * *「 M E N U 」* * * * * * * * * *\n");
	printf("*   一つ前に戻りたい場合は「b」を入力   *\n");
	printf("*   続けたい場合は「g」を入力           *\n");
	printf("*   カレンダーの確認は「c」を入力       *\n");
	printf("*   プログラムの終了は「x」を入力       *\n");
	printf("* * * * * * * * * * * * * * * * * * * * *\n\n");


	/*西暦の入力*/
	while(1)
	{
		printf("西暦を入力してください(1970年から2038年まで有効)>>");
		scanf("%d", &year);
		fflush(stdin);
		
		if(year > 1969 && year < 2039)
		{
			n = select(n);
		}
		else
		{
			n = error(n);
			continue;
		}
		break;
	
	}

	int n=0;
	/*月の入力*/
	while(1)
	{
		printf("月を入力してください>>");
		scanf("%d", &month);
		fflush(stdin);
		
		if((month > 0) || (month > 13)) 
		{
			n = select(n);
		}
		else
		{
			n = error(n);
			continue;
		}
		break;
	}
	return 0;
}

select関数ですが。

int select(int out)
{
	char n=0,str[256];
		printf("次の操作を「MENU」から選んでください\n");
		scanf("%255[^\n]%*[^\n]",str);
		getchar();	
			if(strlen(str) == 1)							
			{
				n = str[0];
			}

				if(n == 'b')							
				{
					「」;
				}
				else if(n == 'g')
				{
					「」;
				}
				else if(n == 'c')
				{
					「」;
				}
				else if(n == 'x')
				{
					「」;
				}
				else
				{
					「」;
				}
	return 0;
}
正常動作の時と、西暦入力後に「b」と入力してしまった場合の2個、同じようなのを用意してあります、これは正常動作の時のです。
とくに「」の部分をどうしようかと思ってます。
西暦入力後に「b」の方では[これ以上は戻れない]なんて文もでるようにしたいのです。

長い文ですがどうかよろしくお願いします。

non
記事: 1097
登録日時: 14年前

Re: カレンダー(ファイルオープンによるメモ機能付き)

#2

投稿記事 by non » 14年前

コンソールプログラムなのですね。

戻るという機能は何のために必要なのでしょうか?同様に「g」もですが。
入力したメモが削除でき、予定ありとしてのマーク「*」が削除されればいいのではないでしょうか。

まずは、年月日を入力して、その月のカレンダーが表示されるように作ってみたらいかがでしょうか?
non

YOU's

Re: カレンダー(ファイルオープンによるメモ機能付き)

#3

投稿記事 by YOU's » 14年前

戻る機能ですが、西暦であれば「10000」と入力されると、不適切な値としてエラーでまた再入力になる。
この戻ると。

普通に入力して「2011」と入力して正常処理、でもやっぱり「2010」で入力したかった!
って時に「b」=Backしてまた西暦の入力になる。
の戻るっていう機能です。

YOU's

Re: カレンダー(ファイルオープンによるメモ機能付き)

#4

投稿記事 by YOU's » 14年前

メモの方を忘れてました。

日付入力で、txtファイルをファイルオープンで呼び出して、なにかしらメモを書く。

すると、その日は「*」で予定ありと表示される。

入力したメモは編集ができるようにしたいです。
ReadオンリーとかWriteオンリーとかではなく。

↑の追加で「g」はgoで次って意味にしてます。

non
記事: 1097
登録日時: 14年前

Re: カレンダー(ファイルオープンによるメモ機能付き)

#5

投稿記事 by non » 14年前

YOU's さんが書きました:戻る機能ですが、西暦であれば「10000」と入力されると、不適切な値としてエラーでまた再入力になる。
この戻ると。

普通に入力して「2011」と入力して正常処理、でもやっぱり「2010」で入力したかった!
って時に「b」=Backしてまた西暦の入力になる。
の戻るっていう機能です。
西暦10000が不適切かどうかは別にして、これは、エラーになるのなら、わざわざ「戻る」コマンドは不要でしょう。
再入力するよりないのですから。

「2011」で正常処理して、その後、「2010」をしたいなら、戻らなくても、またカレンダーの確認「c」をすればよいだけではないのかな。

いずれにしてもメニューの階層がわかりにくいです。
例えば
1 カレンダーの表示
    年月を入力しその月のカレンダーを表示する。
2 スケジュール表示
    1で表示されている月の日を入力してメモを表示する。
3 スケジュール入力
    1で表示されている月の日を入力してメモを入力する。
4 スケジュール削除
    1で表示されている月の日を入力してメモを削除する。
5 終了
    プログラムを終了する。

のようにです。
2,3,4はまとめて、日を入力して既にメモがあれば表示し、
 「a:削除」「b:編集」「c:戻る」に分かれるようにし、メモがない日なら、
 「a:入力」「b:戻る」ようなサブメニューにしてもいいでしょう。
non

YOU's

Re: カレンダー(ファイルオープンによるメモ機能付き)

#6

投稿記事 by YOU's » 14年前

そうですね、戻るとかの確認は不要ですね。

「b」を入力したらどこからでもひとつ前に戻れるは変わらずです。
ただ確認がいちいち出るのをなくしたいと思います。

「2011と入力、でも2010で入力したかった」、ですが。
これはカレンダーの表示で対応ではなく。

前の選択種に戻るという仕様にしてくれってことなので。
ただカレンダー表示後はいつでも「c」で確認できる。

簡単な仕様書としてですが。まとめると。

1.西暦入力
2.月入力
3.カレンダー表示
4.日付を選択
5.その日にメモ書きこむor読み込む?(制限全角50文字)
6.書き込んだ結果はtxtファイルで同ディレクトリに出力。
7.メモを追加した日は「*」で表示。→4に戻る。

どこからでも前の入力に戻れる。また、どこからでもプログラムを終了できる。
これも条件になってます。

このような感じで作ろうと思ってます。

やはり初心者にはかなりハードル高いようで・・・

参考にできる例文などあればわかりやすいのですが。

メモ付きカレンダーなんてものはないようで・・(´・ω・`)

non
記事: 1097
登録日時: 14年前

Re: カレンダー(ファイルオープンによるメモ機能付き)

#7

投稿記事 by non » 14年前

>前の選択種に戻るという仕様にしてくれってことなので。

自分の勉強のために自分で仕様を決めて作っているのではなさそうですね。
誰かから、頼まれて実用的なものを作ろうとしているのでしょうか?
C言語の勉強ではなく、ただ単に実用的なものを作ろうというのなら、
VisualBasicなどで作ると早いです。コンソールアプリですと、とても使えるものが
できるとは思えません。最低でもDxLibを使うとか。Excelで作るという方法も
ありますね。
non

YOU's

Re: カレンダー(ファイルオープンによるメモ機能付き)

#8

投稿記事 by YOU's » 14年前

C言語限定でしかもコンソール表示でのメモ付きカレンダー。
プログラム勉強しはじめて1ヶ月ちょいですが。
会社の方からこういうの作ってみてと。(勉強になるからと)

製品化しないが、すぐにでも使える実用的なものをということで・・・

「5年やってる人でも考えるのに半日はかかるから・・・」
「いっぱい悩んで、いろんな考え方で作ってみなさい」

それで出されたのが上の条件などです。
期限はなしですが、いつもなにかしらのプレッシャーが・・・

一つ上の先輩に聞いたら、「オレそんな難しいのできない」
1年やった先輩ですらできないのを1ヶ月の自分がやっております。

ただいまも悩み中ですが、もう少し頑張ってみようと思います。
最初に投稿したソースと変わると思いますので。

またなにかわからなくなったらみなさんに助言を貰いたいです。

答えていただいた方ありがとうございます、いろいろと参考にいたします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: カレンダー(ファイルオープンによるメモ機能付き)

#9

投稿記事 by softya(ソフト屋) » 14年前

はじめまして。

最初から読まさせていただきました。それとcodeタグも加えさせていただきました。
「いっぱい悩んで、いろんな考え方で作ってみなさい」と指示されているなら機能不足にならない限り仕様は使いやすく変えても良いと思います。
YOU's さんが書きました:一つ上の先輩に聞いたら、「オレそんな難しいのできない」
1年やった先輩ですらできないのを1ヶ月の自分がやっております。
それは謙遜か、もし出来ないなら問題がありますね。
そんなに難しいものではありません。少しづつ機能を追加していけば良いと思います。

>とくにこれから先のファイルRead、Writeの部分をどうコーディングすればいいのかわかりません。

単体のread/writeプログラムをそれぞれ作れますか?
そこから始めて見てはどうでしょうか?

>また、一回一回の入力ごとに前に戻れたり指定のキーで終了も、どのようにすればいいのか・・・

状態遷移と言う考えを使います。
int state;とか変数を宣言して
仕様の入力関連の定数を宣言
enum {
STATE_INPUT_YEAR,
STATE_INPUT_MONTH,
省略
};
初期値を設定
state = STATE_INPUT_YEAR;
このstateでswitchして呼び出す機能を変えるだけです。
動作を切り替えるときはstate = STATE_INPUT_MONTH;などと入力します。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

YOU's

Re: カレンダー(ファイルオープンによるメモ機能付き)

#10

投稿記事 by YOU's » 14年前

返信ありがとうございます。

カレンダーにread/writeもちょっとわからないですね。
「FILE *fpっていうのを使うとできるよ」
あとは調べて・・・という感じでした。

状態遷移?

swith~caseですかね。

まだ、このあたりも十分には理解できないです。
教えていただいたのにすいません。

例文を書いていただけると私としてはわかりやすいです。
文字だとイメージしずらいので。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: カレンダー(ファイルオープンによるメモ機能付き)

#11

投稿記事 by softya(ソフト屋) » 14年前

YOU's さんが書きました:カレンダーにread/writeもちょっとわからないですね。
「FILE *fpっていうのを使うとできるよ」
あとは調べて・・・という感じでした。
カレンダー云々の前にテキストファイルの入出力を勉強するってことですね。
テキストファイルを読み込んでprintfで表示したり。
テキストファイルを作るプログラムを組んでみてください。
それが出来るようになったら、カレンダー処理の関数として組み込むことを考えましょう。
YOU's さんが書きました:状態遷移?

swith~caseですかね。

まだ、このあたりも十分には理解できないです。
教えていただいたのにすいません。

例文を書いていただけると私としてはわかりやすいです。
文字だとイメージしずらいので。
元のコードと仕様を生かしたまま組んでみましたが操作性が良いと言えませんね。
あまりに具体的にヒント出しすぎなので、上の人にこのまま見せると自分でやってないね?とバレる思われると思います。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//	プロトタイプ宣言
int select(int selb,int selg,int selc,int selx);
void error(int n);

//	状態管理の定数
enum {
	STATE_INPUT_YEAR,	//	年を入力
	STATE_INPUT_MONTH,	//	月を入力
	STATE_CALENDAR,		//	カレンダー表示
	STATE_INPUT_DATE,	//	日付を選択
	STATE_INPUT_MEMO,	//	メモを入力
	STATE_END,			//	終了
};

//	メイン
int main(void)
{
	int state = STATE_INPUT_YEAR;
	int year,month;
	char i,n=0,str[256];

	printf("* * * * *「 M E N U 」* * * * * * * * * *\n");
	printf("*   一つ前に戻りたい場合は「b」を入力   *\n");
	printf("*   続けたい場合は「g」を入力           *\n");
	printf("*   カレンダーの確認は「c」を入力       *\n");
	printf("*   プログラムの終了は「x」を入力       *\n");
	printf("* * * * * * * * * * * * * * * * * * * * *\n\n");

	//	メニューループ
	while( 1 ) {
		//	状態別の処理
		switch( state ) {
		case STATE_INPUT_YEAR:
			/*西暦の入力*/
			while(1) {
				printf("西暦を入力してください(1970年から2038年まで有効)>>");
				scanf("%d", &year);
				fflush(stdin);
				if(year > 1969 && year < 2039) {
					state = select(state,STATE_INPUT_MONTH,STATE_CALENDAR,STATE_END);
					break;
				} else {
					error(year);
					continue;
				}
			}
			break;

		case STATE_INPUT_MONTH:
			/*月の入力*/
			while(1)
			{
				printf("月を入力してください>>");
				scanf("%d", &month);
				fflush(stdin);
				if((month > 0) || (month > 13)) {
					state = select(state,STATE_CALENDAR,STATE_CALENDAR,STATE_END);
					break;
				} else {
					error(month);
					continue;
				}
			}
			break;
		}

		//	省略。自分で考えてみてください。
	}

	return 0;
}

//	メニュー選択
int select(int selb,int selg,int selc,int selx)
{
	char n=0,str[256];
	printf("次の操作を「MENU」から選んでください\n");
	scanf("%255[^\n]%*[^\n]",str);
	getchar();  
	if(strlen(str) == 1)                            
	{
		n = str[0];
	}

	if(n == 'b')                            
	{
		return selb;
	}
	else if(n == 'g')
	{
		return selg;
	}
	else if(n == 'c')
	{
		return selc;
	}
	else if(n == 'x')
	{
		return selx;
	}
	return 0;
}


void error(int n)
{
	printf( "入力された数値(%d)はエラーです。\n", n  );
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

YOU's

Re: カレンダー(ファイルオープンによるメモ機能付き)

#12

投稿記事 by YOU's » 14年前

おぉ、ありがとうございます。

操作性は・・・やはりですよね。
一回一回確認が出るのは仕様ということで・・・

あとは/省略/の部分になんとか、read/writeのカレンダーメモを作って。
勉強してなんとかできるかな・・・



あと、この部分で気になったのが。

コード:

    if(n == 'b')                            
    {
        return selb;
    }
    else if(n == 'g')
    {
        return selg;
    }
    else if(n == 'c')
    {
        return selc;
    }
    else if(n == 'x')
    {
        return selx;
    }
MENU選択時のエラーはどうすればよいでしょう?

menu_errorの関数を作って、エラー表示を出し。
そこからまたMENUの操作に戻りたいのですが。

それと、西暦入力後にまた西暦入力に「b」で戻りたい場合はどうすればいいでしょうか?

疑問ばかりですいません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: カレンダー(ファイルオープンによるメモ機能付き)

#13

投稿記事 by softya(ソフト屋) » 14年前

YOU's さんが書きました:MENU選択時のエラーはどうすればよいでしょう?
menu_errorの関数を作って、エラー表示を出し。
そこからまたMENUの操作に戻りたいのですが。
select関数の中にエラー表示を作ったほうが早いでしょうね。
で、エラーならselect関数内でループすれば良いと思います。
YOU's さんが書きました: それと、西暦入力後にまた西暦入力に「b」で戻りたい場合はどうすればいいでしょうか?
今のものはそうなっているはずですか?
あっ私のSTATE_INPUT_MONTHの
state = select(state,STATE_CALENDAR,STATE_CALENDAR,STATE_END);
は間違いですね。
state = select(STATE_INPUT_YEAR,STATE_CALENDAR,STATE_CALENDAR,STATE_END);
が正しいです。

ちなみに、cでカレンダーに行くことになっていますが、年と月が確定していないと表示できませんので注意してくださいね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

YOU's

Re: カレンダー(ファイルオープンによるメモ機能付き)

#14

投稿記事 by YOU's » 14年前

ループ処理も完了。

ホントにありがとうございます。

あとは頑張って、カレンダーとメモ。

それと途中終了くらいかな?

またわからなくなったら質問したいと思います。

その時はどうかまたよろしくお願いします。

閉鎖

“C言語何でも質問掲示板” へ戻る