• 締切済み

入力値のチェック(西暦、万年カレンダ)C言語

入力値が範囲内であるかの判定、違ったらもう一度繰り返すプログラムを作成したいのですが、うまく出来ません。よろしくお願いします。 初心者なので、判りやすく説明していただけると助かります。 #include <stdio.h> void main(){ int a , year ; printf(" 西暦入力--> "); scanf("%d",year); for( a = 0 ; a < 1 ;){ if( year >= 1 && year <=9999 ){ a = a + 1 ; }else{ printf("1年~9999年で入力せよ\n"); } } } scanf()の辺りを変えなければと思っているのですが、どうすればよいのかわかりません。scannf()意外に何を使った方が良いですか? パラメータはどうすればよいですか? 祝日を判定するやり方もわかれば教えていただけませんか? サイトがあったら、URLお願いします。 @@@@@ ↑のプログラムがすべて左よりになってしまったのですが、どうすれば段差をつけれますか?

みんなの回答

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.7

Hantei_func(Yasumi_func?)内、year,day,monthには何の意味が? Input_funcで読み込んだ内容をDisplay_funcには渡しているが、Hantei_funcには渡していないので、Hantei_funcから見ることが出来ない。 Hantei_func/Yasumi_func 関数名の不一致。 参考:年月日を入力、曜日を含めて出力する #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define BUF_SIZE 256 #define SUN 0 #define MON 1 #define TUE 2 #define WED 3 #define THI 4 #define FRI 5 #define SUT 6 void GetDays(int *, int *, int *); void GetWeek(int , int , int , int *); int main(int argc, char *argv[]) {  int nYear,nMonth,nDay;  int nWeek;  GetDays(&nYear, &nMonth, &nDay);  GetWeek(nYear,nMonth,nDay,&nWeek);  printf("%04d年%02d月%02d日",nYear,nMonth,nDay);  switch(nWeek) {  case SUN:   printf("(日曜日)です。\n");   break;  case MON:   printf("(月曜日)です。\n");   break;  case TUE:   printf("(火曜日)です。\n");   break;  case WED:   printf("(水曜日)です。\n");   break;  case THI:   printf("(木曜日)です。\n");   break;  case FRI:   printf("(金曜日)です。\n");   break;  case SUT:   printf("(土曜日)です。\n");   break;  default:   printf("(?曜日)です。\n");   break;  }  return 0; } void GetDays(int *npYear, int *npMonth, int *npDay) {  char szBuf[BUF_SIZE]; // BUF_SIZEは十分に大きい値  int nLastDay[12] = {31,28,31,30,31,30,31,31,30,31,30,31};  char c;  int i;  while(1) {   i = 0;   printf(" 西暦 > ");   while ((c = getchar()) != EOF) {    if(isdigit(c)) {     szBuf[i] = c;     i++;    }else if(c == '\n') {     break;    }   }   szBuf[i] = '\0';   *npYear = atoi(szBuf);   if(*npYear > 0 && *npYear < 10000) {    break;   } else {    printf(" 1 から 9999 で入力してください\n");   }  }  while(1) {   i = 0;   printf(" 月 > ");   while ((c = getchar()) != EOF) {    if(isdigit(c)) {     szBuf[i] = c;     i++;    }else if(c == '\n') {     break;    }   }   szBuf[i] = '\0';   *npMonth = atoi(szBuf);   if(*npMonth > 0 && *npMonth < 13) {    break;   } else {    printf(" 1 から 12 で入力してください\n");   }  }  while(1) {   i = 0;   printf(" 日 > ");   while ((c = getchar()) != EOF) {    if(isdigit(c)) {     szBuf[i] = c;     i++;    }else if(c == '\n') {     break;    }   } //  printf("\n");   szBuf[i] = '\0';   *npDay = atoi(szBuf);   if(*npDay > 0 && *npDay <= nLastDay[(*npMonth)-1]) {    break;   } else {    printf(" 1 から %d で入力してください\n",nLastDay[(*npMonth)-1]);   }  }  fflush(stdin); } void GetWeek(int nYear, int nMonth, int nDay, int *npWeek) {  if(nMonth == 1 || nMonth == 2) {   nYear--;   nMonth += 12;  }  *npWeek = (nYear + (int)(nYear/4) - (int)(nYear/100) + (int)(nYear/400) + (int)((13*nMonth + 8)/5) + nDay) %7; }

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.6

コンパイラは何を使っていますか? 最新ではないCでは、変数宣言は関数の先頭に書かなければいけませんよ? Yasumi_func内 year, month, day, i が、定義だけで値が入っていないが。

shutoko-
質問者

補足

ご指摘ありがとうございます。下記のように変更してみました。 void main(){ int year = 0 ; int month = 0 ; Input_func( &year , &month ); Display_func( year , month ); return; } /* 入力値判定 */ void Input_func( int *year , int *month ) {質問内容部分です。} /*結果表示関数 */ void Disp_func( int year , int month ) {   int week , i , leap , day , *shuku , *furikae ;   int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};   int d = 0; 略 for( i=0 ; i<week ; i++ ){ printf(" "); } for(day=1 ; day<=days[month] ; day++ ){ ★★Yasumi_func( int &shuku , int &furikae );   if(i==0){     printf(" @%2d",day);   }else if(i==*shuku){     printf(" #%2d",day);   } else if(i==*furikae){     i = 1;     printf(" &%2d",day+1);   }else if(i==6){     printf(" *%2d",day);   }else{     printf(" %2d",day);   } 略 @:日曜日 *:土曜日 &:振替休日 #:祝日 return; } /* 祝日判定関数 */ void Hantei_func( int *yasumi , int *kae ) { int year , month ; int day = 0 , i = 0 ; if((month==3 && day== (int)(20.8431 + 0.242194*(year-1980) - (year-1980)/4)) 略   {   if(i == 0){     *kae = i ;   }   else{     *yasumi = i;   } } } day=0,i=0;としました。 コンパイラはボーランドC++を使っています。 チェック、指摘お願いいたします。

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.5

> Yasumi_func( int &yasumi , int &kae ); int yasumi,kae; Yasumi_func( &yasumi , &kae ); としてみては。

shutoko-
質問者

補足

回答ありがとうございます。 試してみたのですが、式の構文エラーとなってしまいました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

getchar() が返す値は文字コードです. 例えば, ASCII を使っている環境で '1' を入力すると getchar() は 49 を返します. いろいろ面倒なので scanf を使う方がいいと思います. まあエラーチェックが問題になることもありますが.... で, 祝日は春分の日と秋分の日を除いて日付か曜日のどちらかで決まるので, 曜日が計算できれば OK かと. Zeller の公式ってのがあります. なお, 春分の日と秋分の日は前年2月1日付けの官報で公表されることになっているので, 厳密にはそれまでに決めることは不可能です.

shutoko-
質問者

補足

ご回答ありがとうございます。 祝日に関して、下記の通りプログラムを作ったのですがうまくいきません。 ご教授お願いします。 void Yasumi_func( int * , int * ); void Display_func( int year , int month ) {   int week , i , leap , day , *yasumi , *kae ;   int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};   int d = 0; **省略**   for( i=0 ; i<week ; i++ ){      printf(" ");   }   for(day=1 ; day<=days[month] ; day++ ){   Yasumi_func( int &yasumi , int &kae ); /* 祝日判定関数 */   if(i==0){     printf(" @%2d",day);   }else if(i==*shuku){      printf(" #%2d",day);   }else if(i==*furikae){     i = 1;     printf(" &%2d",day+1);   }else if(i==6){     printf(" *%2d",day);   }else{     printf(" %2d",day);   } 略 printf("@:日曜日 *:土曜日 &:振替休日 #:祝日 \n"); return; } /* 祝日判定関数 */ void Yasumi_func( int *yshuku , int *furikae ) { int year , month , day , i ; if((month==3 && day== (int)(20.8431 + 0.242194*(year-1980) - (year-1980)/4))   || (month==9 && day==(int)(23.2488 + 0.242194*(year-1980) - (year-1980)/4))   || (month==1 && day==1)   || (month==1 && day>7 && day<15 && i==1)   || (month==2 && day==11) 略   || (month==10 && day>7 && day<15 && i==1)   || (month==11 && day==3) || (month==11 && day==23)   || (month==12 && day==23))   {     if(i == 0){       *furikae = i ;      /* 振替休日 */     }else{       *shuku = i; /* 祝日 */     }   } } このように作ったのですが、   Yasumi_func( int &yasumi , int &kae ); 祝日判定関数を呼びたいのですが「式の構文エラー」となってしまいます。 この他   if(i == 0){     *furikae = i ;   }else{     *shuku = i;   } この部分も自信がないので、アドバイスお願いいたします

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.3

getchar()で任意の整数をとる char szBuf[BUF_SIZE]; // BUF_SIZEは十分に大きい値 char c; int n; int i = 0; while ((c = getchar()) != EOF) {  szBuf[i] = c;  i++; } szBuf[i] = '\0'; n = atoi(szBuf); 数字以外の入力や文字数オーバーの処理には対応していないので、必要ならば追加すること。

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.2

修正版。 動作未確認。 #include <stdio.h> int main(int argc, char *argv[]){  int year;  while(1) {   printf(" 西暦入力--> ");   scanf("%d",&year);   if( year >= 1 && year <=9999 ){    break;   }else{    printf("1年~9999年で入力せよ\n");   }  }  return 0; }

shutoko-
質問者

補足

回答ありがとうございます。 この他に今getcharを使った方法を考えているのですが、ご教授お願いいたします。 #include <stdio.h> void main(){   int a , year ;   printf(" 西暦入力--> ");     while ((year = getchar()) != EOF)     for( a = 0 ; a < 1 ;){       if( year >= 1 && year <=9999 ){         a = a + 1 ;       }else{         printf("エラー:1年~9999年で入力せよ\n");       }     } } カレンダのmain()に関連付ける為本来は下記のようにします。 void main(){   int a , i , year ; ↓↓↓ void Input_func( int *year , int *month ) 西暦=4文字なので for(i=0;i<5;i++); としてみたのですが、794年など4文字に満たない時どうすればよいのか解りません

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.1

scanfには「変数のアドレス」を渡しましょう。 この場合は &year ですね。 ここでは、行頭の「半角スペース」「タブ文字」はきえてしまうので「全角スペース」でインデントしましょう。

shutoko-
質問者

お礼

>scanfには「変数のアドレス」を渡しましょう。 回答ありがとうございます。頭に入れておきます。 >「全角スペース」でインデントしましょう。 うまくできました。ありがとうございますm(__)m

関連するQ&A

  • C言語について

    次のような問題です。 問 自然数nを入力し、nを3で割って割り切れるかどうかを判定し結果を表示する。「割り切れる」、「1余る」、「「2余る」のいずれかが入るものとする。 このようなものをつくりました。 #include<stdio.h> int main(void) { int n; printf("自然数:"); scanf("%d",&n); if(n==0){ printf("割り切れる\n"); }else if(n==1){ printf("1余る\n"); }else{ printf("2余る"); } return(0); } これで合っているかよろしくお願いします。

  • C言語プログラム

    2つの整数を入力させ、それらが等しい場合hitoshii、異なる場合にはhitoshikunaiと出力するプログラムを作りたいのですが、うまくいきません。間違っているところを教えてください。 #include<stdio.h> #include<conio.h> void main() { printf("整数を入力してください:"); int number1; scanf("%d",number1); printf("整数を入力してください:"); int number2; scanf("%d",number2); if(number1==number2) { printf("hitoshii"); } else { printf("hitoshikunai"); } getch(); }

  • C言語 関数問題

    西暦年yearを引数として受け取り,閏年かどうかの判定結果を戻り値として返す関数leap_year()を作成せよ. ただし,leap_year()は,閏年の場合は1を返し,そうでない場合は0を戻り値として返すものとする. 提出するプログラムは,関数leap_year()だけでなく,メイン関数main()も含む下記プログラムを完成させる形で作成する #include <stdio.h> /* ここに関数leap_year()のプロトタイプ宣言を記述する */ int main() { int i, year[3]; for (i=0; i<3; i++) { printf("西暦年を入力してください"); scanf("%d", &year[i]); if (leap_year(year[i]) == 1) { printf("閏年です.\n"); } else { printf("閏年ではありません.\n"); } } } /* ここに関数leap_year()を定義する */

  • c言語についての質問です。

    #include<stdio.h> int main(void){ int a; printf("1文字たいぷしてください。\n"); scanf("%d",&a); if(a>=65 && a<=90){ printf("大文字です。\n"); } else if(a>=97 && a<=122){ printf("小文字です。\n"); } else{ printf("大文字でも小文字でもありません\n"); } return 0; } このプログラムは正しくなくて、 intをchar %dを%cにかえなければなりません。 なぜintはダメなんでしょうか? できれば丁寧に教えてください。 お願いします。

  • 今、C言語の勉強をしていて、「西暦と月をscanfで入力し、”西暦●●

    今、C言語の勉強をしていて、「西暦と月をscanfで入力し、”西暦●●年の●月は●日です”というプログラムを完成させなさい」という問題がありました。 また、条件が「4の倍数で、かつ100の倍数でない場合か、400の倍数の場合は閏年である」また 「西暦が0以下のとき、月が1以下12以上の場合はエラーメッセージを表示させなさい。」というものです。 そこで、コーディングした結果、下記のようになりました。 #include <stdio.h> main() { int y,m,d; printf("西暦=");scanf("%d",&y); printf("月=");scanf("%d",&m); if(y<0 || d>1 && d<12) printf("エラーです。"); else if(m==1 || m==3 || m==5 || m==7 || m==8 || m==10 || m==12) d=31; printf("西暦%d年の%d月は%d日です。",y,m,d); else if(m==4 || m==6 || m==9 || m==11 ) d=30; printf("西暦%d年の%d月は%d日です。",y,m,d); else if(m==2 && y%4==0 && y%100>0 || y%400==0) d=29; printf("西暦%d年の%d月は%d日です。",y,m,d); else d=29; printf("西暦%d年の%d月は%d日です。",y,m,d); } これを、学校の先生が開発したコンパイラで文法チェックを施したところ、 「予約語elseは使用できません」と文法エラーがでました。 「else」は、if文のthen/elseの意味で利用したのにそういう風にとらえてくれませんでした。 また、字下げは適当にやっているだけですので気にしないでください。 これ、どこかおかしいところありますか・・・?

  • C言語プログラミング

    台形の面積を求めるプログラムを作りたいのですが、最後のmensekiの出力の仕方がわかりません。printf以降のプログラムを教えてください。 #include<stdio.h> #include<conio.h> void main() { int number1,number2,number3,menseki; printf("上底を入力してください:"); scanf("%d",&number1); printf("下底を入力してください:"); scanf("%d",&number2); printf("高さを入力してください:"); scanf("%d",&number3); menseki=(number1+number2)*number3/2; printf( ここがわかりません getch(); }

  • C言語入門者です。プログラムの添削をお願いします。

     任意の西暦年を入力し、その年がオリンピックの開催年(夏季・冬季問わず)かどうかを判定するプログラムを作ろうと思っています。  #include<stdio.h> int main(void) {     int year, rest;     rest = year % 4;     printf("オリンピック(夏季・冬季問わず)が開催される年(西暦)を一つ答えなさい。");     scanf("%d", year);     if(rest == 0) printf("正解!夏季五輪!");     if(rest == 2) printf("正解!冬季五輪!");     if(!(rest == 0 || rest == 2)) printf("不正解!");     return 0; } 夏季五輪開催年を入力した場合、「正解!夏季五輪!」 冬季五輪開催年を入力した場合、「正解!冬季五輪!」 それ以外の場合、「不正解!」 と画面に表示されるようにしたいのです。    しかし、year にどんな数値を入力しても、「正解!夏季五輪!」としか表示されません。どこが間違っているのでしょうか?添削よろしくお願いします。

  • C言語について

    「キーボードから10個の実数を入力し、それらの平均を求めるプログラムを作れ。」という問題で私は、 #include <stdio.h> void main(void) { float A; float a,b,c,d,e,f,g,h,i,j; printf("実数を入力してください:"); scanf("%f",&a); scanf("%f",&b); scanf("%f",&c); scanf("%f",&d); scanf("%f",&e); scanf("%f",&f); scanf("%f",&g); scanf("%f",&h); scanf("%f",&i); scanf("%f",&j); A=(a+b+c+d+e+f+g+h+i+j)/10; printf("平均は%fです.\n",A); } と考えたのですが、もっとすっきりとしたプログラムはないのでしょうか?もっとシンプルにしたいのです。教えて下さい。よろしくお願いします。

  • C言語について

    こんばんわ。協力お願いします。 2問あります。 1問目です。 西暦年yearを引数として受け取り, 閏年かどうかの判定結果を戻り値として返す関数leap_year()を作成せよ. ただし,leap_year()は,閏年の場合は1を返し, そうでない場合は0を戻り値として返すものとする. 提出するプログラムは,関数leap_year()だけでなく, メイン関数main()も含む下記プログラムを完成させる形で作成する。 #include <stdio.h> /* ここに関数leap_year()のプロトタイプ宣言を記述する */ int main() { int i, year[3]; for (i=0; i<3; i++) { printf("西暦年を入力してください"); scanf("%d", &year[i]); if (leap_year(year[i]) == 1) { printf("閏年です.\n"); } else { printf("閏年ではありません.\n"); } } } /* ここに関数leap_year()を定義する */ 2問目です。 mのn乗を計算する関数power()を作成せよ. ただし,関数power()はm,nを引数とし, 戻り値としてmのn乗の値を返すものとする. m,nは,正整数とする.プログラムには, 関数power()だけでなく,m,nを入力し, mのn乗を出力するメイン関数main()を含むものとする. main()は,power()の前に記述すること. また,power()のプロトタイプ宣言も記述すること。 よろしくお願いします。

  • C言語のポインタについての質問です。

    C言語のポインタについての質問です。 2つのプログラムを作り、片方で数値を入力し、 もう片方でその数値を読み取りたいと思っています。 数値入力のプログラムは次のようになっています。 #include<stdio.h> void main(void){ int A=1; int *p; p=&A; printf("%p\n",p); } この実行結果は「0012FF88」となりました。 次にこの「0012FF88」というアドレスを使って「1」を読み取る 別のプログラムを作りたいと思っています。 #include<stdio.h> void main(void) { int add; int a; printf("アドレスは?\n"); scanf("%x",&add);    //「0012FF88」と入力 a=*(int*)add; printf("%x---->%d",&add,a); } このようなプログラムを作ってコンパイルできたのですが、 実行してアドレスを打ち込むと「Win32の例外が発生しました」 となって実行できません。 何かよい方法やプログラムの問題などありましたら 教えて頂けませんか?

専門家に質問してみよう