• ベストアンサー

エラー処理

万年カレンダーを作っています。 while(1){ printf(" 西暦年>"); scanf("%d",&year); /*西暦年入力*/ printf("   月>"); scanf("%d",&month); /*月入力*/ if(year>0 && month>0 && month<13){     break; } else{ printf("正しく入力してください\n"); } 上記のように、数字のエラー処理をしたのですが、これに数字以外のモノが入力された場合のエラー処理も追加しなければなりません。

質問者が選んだベストアンサー

  • ベストアンサー
  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

scanf("%d",&year); の段階で入力文字が数値でない場合はyearに代入されないです scanfの戻り値が0かどうかで判断するのはどうでしょう。

yoro4423
質問者

お礼

ありがとうございました。 scanfの戻り値を利用して、エラー処理解決できました。

yoro4423
質問者

補足

すみません。scanfの戻り値が0かどうか判断するというのはどういうことで、どういうふうにするのですか。初心者なもので、詳しく教えていただけませんか?

その他の回答 (3)

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.4

(意外というかヒネクレ?た「回答」) ★質問者様の最初に示されたソースの「エラー処理」で十分です。 《根拠》    ・scanf( "%d", &year ); で、      例えば、2nd と入力すると、year には 2       、second と入力すると、year は「初期値」のまま  ・たまたま、その「初期値」が正であれば、その「初期値」年の処理。    ・たまたま、その「初期値」が負であれば、「エラー処理」。   なんの不具合もありませんよね。 ----------------------------------------------- (というか) 変数の宣言で、int year = 2008, month = 2; と初期化しておき、 「数字以外のモノが入力された場合」は、2008 年 2 月のカレンダーを《強制的に》作るように「しかけ」を施しておけばいいのでは。 ★それで、思考の重点を「指定年月の朔日の曜日」を求める方に向ける。 ----------------------------------------------- (とはいうものの) >初心者なもので、詳しく教えていただけませんか?  scanf() 等について、参考URLなどで調べましょう。

参考URL:
http://www.bohyoh.com/CandCPP/C/Library/index.html
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★アドバイス >どこがおかしいのでしょうか。  ↑  整数の変数yearに対して文字検査のisdigit()関数を使っているところです。  正しくは文字列の変数yearに対して文字検査を使います。  char year[ 10 ];    scanf( "%s", year );  このようになります。  scanfは『%s』になります。  同様にmanthも文字列で入力できるようにします。 ・文字列の最後は『\0』です。

yoro4423
質問者

補足

ご指摘ありがとうございました。 確かにそうでした。

  • shimix
  • ベストアンサー率54% (865/1590)
回答No.1

>数字以外のモノが入力された場合のエラー処理も追加しなければなりません。 そうですね。数字範囲チェックより前でチェックしないといけません。 で、何が質問なのでしょうか?補足してください。

yoro4423
質問者

補足

すみません。そうですよね。 数字かどうか判定すればよいからisdigit関数を使用すればよいと思い、組もうとしたのですが、出来ませんでした。 while(1){ printf(" 西暦年>"); scanf("%d",&year); /*西暦年入力*/ printf("   月>"); scanf("%d",&month); /*月入力*/ if(isdigit(year)!=0 && isdigit(month)!=0){ if(year>0 && month>0 && month<13){ break; } } else{ printf("正しく入力してください\n"); } どこがおかしいのでしょうか。

関連するQ&A

  • ポインタの初歩でお聞きしたいです。

    今カレンダーを作っていて、西暦と月を入力するとその時のカレンダーを表示するだけです。 関数で、「関数は戻り値を1ッコしか返せないので、複数個返すことができるようにするには」みたいなところを勉強中です。 int main() { int year,month,week,days;       : getYearMonth(&year,&month);       : return 0; } getYearMonth(int *py,int *pm) { printf("西暦と月を2009 3のようにスペースで区切って入力してください\n"); while(1) { scanf("%d %d",py,pm); //*ここがちょっとわからないところです* if((*pm>=1)&&(*pm<=12)){ //1から12月まででそれ以外の数字なら break; // printf("入力間違いです\n") } return; } "*pyや*pm"がscanfのところにいくと'*'とって'&'をつけないのは"pyとpm"がアドレスを指すってモノっていうことですか? getYearMonth(&year,&month);ではyearとmonthには'&'アドレスのマークをつけますけれど、それは下とおなじですよね? -------------------------------------------------------------- int x; //変数の宣言 int *p; //ポインタ変数の宣言 p=&x; //ポインタ変数の初期化 ここが、getYearMont(&year,&month);と一緒? *p=10; //値(アドレス)の代入 scanf()で値を入れてるところと同じ? ということでしょうか? ちょっと、ポイントで引っかかってます。 ポインタってデスクトップのショートカットアイコンみたいなものです よって、前になんかで見たんですが。イメージがつかみづらいです。 もしかしたら、質問自体ちぐはぐな事を言ってたらすみません。

  • カレンダー作成

    C言語初心者です。 西暦と月を入力してその月のカレンダーを作成するプログラムの問題なのですが #include <stdio.h> #define MMAX 12 #define COMP (year - 1) int main(void) {  int i, j, year, month, day, youbi, ycnt, mcnt = 0;  int mday[MMAX] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};  printf("西暦と月を入力して下さい-->");  scanf("%4d%2d, &year, &month");  if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)   mday[1] = 29;  for (i = 0; i < [A]; i++) {   mcnt += mday[i];  }  mcnt++;  [B] = ((COMP + COMP / 4 - COMP / 100 + COMP / 400) + mcnt) % 7;  printf("\n%4d 年%2d 月\n", year, month);  printf("----------------------------\n");  printf(" 日 月 火 水 木 金 土\n");  for (j = 0, ycnt = 0; j < youbi; j++, ycnt++) {   printf(" ");  }  for (day =1; day <= mday[month - 1]; day++) {   if ([C])    printf("[%2d]", day);   else    printf(" %2d ", day);   ycnt++;   if ([D]) {    printf("\n");    ycnt = 0;   }  }  return (0); } [A]、[B]、[C]、[D]に答えを入れなきゃいけないのですが私が考えた答えだと カレンダーの表示すらされません。どこがいけないのでしょうか? #include <stdio.h> #define MMAX 12 #define COMP (year - 1) int main(void) {  int i, j, year, month, day, youbi, ycnt, mcnt = 0;  int mday[MMAX] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};  printf("西暦と月を入力して下さい-->");  scanf("%4d%2d, &year, &month");  if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)   mday[1] = 29;  for (i = 0; i < month; i++) {   mcnt += mday[i];  }  mcnt++;  youbi = ((COMP + COMP / 4 - COMP / 100 + COMP / 400) + mcnt) % 7;  printf("\n%4d 年%2d 月\n", year, month);  printf("----------------------------\n");  printf(" 日 月 火 水 木 金 土\n");  for (j = 0, ycnt = 0; j < youbi; j++, ycnt++) {   printf(" ");  }  for (day =1; day <= mday[month - 1]; day++) {   if (youbi = 0)    printf("[%2d]", day);   else    printf(" %2d ", day);   ycnt++;   if (youbi > 7) {    printf("\n");    ycnt = 0;   }  }  return (0); } よろしくお願いします。

  • 日齢計算プログラム

    誕生年月日を入力し、本日時点での日齢を計算するプログラムを作成する。日齢とは誕生の日から本日までの経過日数である(昨日生まれた人の日齢は1日)。誕生年の入力は西暦ではなく和暦とする。出力は画面に出力するとともに、ファイル“abc.txt”に出力する。 現段階では一年を365日とし、毎月の日数を正しくとらえて計算するプログラム。 ただし、うるう年は考慮していないのでこの場合の日齢も正確ではない。○月×日が一年の最初の日から何日目であるかを計算する関数を作る。 1月 1/1からの日数=日 2月 1/1からの日数=日+31 3月 1/1からの日数=日+59 というように作っています。 ところがコンパイルをすると”gfewy.cpp(60) : error C2601: 'main' : ローカル関数の定義が正しくありません。”というエラーメッセージが出てきます。 どのように訂正すればいいのでしょうか、教えてください。 #include <stdio.h> int day_count(int x,int y) { int z; switch(x){ case 1: z=y; break; case 2: z=y+31; break; case 3: z=y+59; break; case 4: z=y+90; break; case 5: z=y+120; break; case 6: z=y+151; break; case 7: z=y+181; break; case 8: z=y+212; break; case 9: z=y+243; break; case 10: z=y+273; break; case 11: z=y+304; break; case 12: z=y+334; break; return(z); } void main (void) { FILE *fp; char nengo; int year_td,month_td,day_td,year_bd,month_bd,day_bd,nichirei; fp=fopen("abc.txt","w"); printf("your birthday\n"); fprintf(fp,"your birthday\n"); printf("input nongou:");scanf("%c",&nengo); fprintf(fp,"input nongou:"); printf("input year:");scanf("%d",&year_bd); fprintf(fp,"input year:"); printf("input month:");scanf("%d",&month_bd); fprintf(fp,"input month:"); printf("input day:");scanf("%d",&day_bd); fprintf(fp,"input day:"); switch(nengo){ case'm': case'M': year_bd=year_bd+1867; break; case't': case'T': year_bd=year_bd+1911; break; case's': case'S': year_bd=year_bd+1925; break; case'h': case'H': year_bd=year_bd+1988; break; default: printf("input nengo is invalid.\n"); } year_td=2007; month_td=10; day_td=22; nichirei=365*(year_td-year_bd)+(day_count(month_td,day_td)-day_count(month_bd,day_bd)); printf("your birthday:year=%d,month=%d,day=%d\n",year_bd,month_bd,day_bd); fprintf(fp,"your birthday:year=%d,month=%d,day=%d\n",year_bd,month_bd,day_bd); printf("your nichirei:%d\n",nichirei); fprintf(fp,"your nichirei:%d\n",nichirei); fclose(fp); } }

  • プログラムの内容

    以下のプログラムは答えとして渡されたものなんですが、 コマンド引数を使ったプログラムの流れがよくわかりません。 簡単に解説してくれる方、いませんか? #include <stdio.h> int leapyear(int year){ if(year%400 == 0) return 1; else if(year%4 == 0 && year%100 != 0) return 1; else return 0; } void addmonth(int *day, int *month, int *year){ *day = 1; (*month)++; if(*month > 12) { *month = 1; (*year)++; } } int main(int argc, char *argv[]){ int year, month, day, a=0, max_days; int month_days[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; if(argc < 2) max_days = 10000; else max_days = atoi(argv[1]); printf("今日は西暦何年 何月 何日? "); scanf("%d%d%d",&year,&month,&day); while(a<max_days) { a++; day++; if(month == 2 && leapyear(year)) { if(day > 29) addmonth(&day, &month, &year); } else { if(day > month_days[month-1]) addmonth(&day, &month, &year); } } printf("今日から%d日後は、%d年%d月%d日です。",max_days, year, month, day); }

  • 西暦・月からカレンダーを表示

    問題文 西暦・月を入力してカレンダーを表示するプログラムを作成せよ。 プログラム全体のことを考える。プログラムの流れとしては、つぎのようになるであろう。  (1)変数の宣言: プログラムの中で使う変数や配列等をすべてここに集めておく。          (2)入力: キーボードから、西暦年の値を読み取る ← scanf( ) 関数  1月から12月まで、以下を繰り返す。  (3)カレンダーの年・月の表示: (例えば、2008年1月 と表示)  (4)各曜日名の表示: 「日 月 火 水 木 金 土」と表示  (5)月の日数の算出: 月の最後の日を計算しておく。(*1~12月以外では誤りとすること)  (6)曜日の算出: 月の初めの日(ついたち)の曜日をツェラー公式で計算しておく。  (7)空列の表示: ついたちの前の空白部分を表示する ← for文 を利用。  (8)各日の表示: 月の各日を順に表示していく ← for文を利用          (土曜の後に改行を入れる) #include <stdio.h> int leapYear(int year) { if (year%400==0||(year%4==0 && year%100!=0)) { return 1; } else { return 0; } } int main(void) { int d,year,m,i; int day[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; /*1~12月までの各月の日数*/ printf("西暦を入力してください:"); scanf("%d",&year); printf("月を入力してください:"); scanf("%d",&m); if(m!=1 & m!=2 & m!=3 & m!=4 & m!=5 & m!=6 & m!=7 & m!=8 & m!=9 & m!=10 & m!=11 & m!=12)/*1~12月以外で日数を出そうとした場合*/ { printf("入力が誤っています。やりなおしてください。\n"); } else{ if (leapYear(year)==1)/*閏年の場合*/ { printf("%d年は閏年です。\n",year); day[1] +=1; } else/*閏年でない場合*/ { printf("%d年は閏年ではありません。\n",year); } i = (year+year/4 -year/100 +year/400 + ( 13*m+8 )/5 + 1) % 7; /*西暦~年・1~12月の1日の曜日について考える*/ printf("日 月 火 水 木 金 土\n"); (7)・・・ (8)・・・ } return 0; } 手順に沿ってやっていく課題なのですが(7)、(8)の部分の表現の仕方が良く分かりません。(求めた月の日数をカレンダー形式に表示する方法・1日の前に空白を入れる等) 過去の質問も見たのですが、いまいち理解できず・・・orz どなたかご教授お願いできないでしょうか・・・。

  • カレンダーのプログラム

    指定した開始月と終了月を入力して、それを横に最大3つまで並べて 納まりきらないときは改行するというプログラムを作りたいです。 イメージとしては、2009年の9月から2009年の12月まで指定した場合は… 2009 / 9              2009 / 10             2009 / 11 1 2 3 4 5 6 7          1 2 3 4 5 6 7           1 2 3 4 5 6 7 8 9 10 11 12 13 14      8 9 10 11 12 13 14       8 9 10 11 12 13 14 15 16 17 18 19 20 21    15 16 17 18 19 20 21    15 16 17 18 19 20 21 21 22 23 24 25 26 27    21 22 23 24 25 26 27    21 22 23 24 25 26 27 28 29 30           28 29 30 31           28 29 30   2009 / 12 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 21 22 23 24 25 26 27 28 29 30 31 (最初の日数などは適当ですし、ちょっとずれてしまっていますがご了承ください。あくまでもイメージなので…) ところが下のプログラムを動作させようとしたところ全く 動きません。何がおかしいために動作しないのでしょうか? よろしくお願いします。 #include<stdio.h> #include<string.h> int getyoubi(int year,int month,int day) { if(month==1 || month==2 ) { year--; month +=12; } return ((year+year/4-year/100+year/400+(13*month+8)/5 + day)%7); } int main(void) { int nen1,tuki1,nen2,tuki2,tukiho,nenho,tukih,w,i,j; char sbuf[3][7][22]; int tuki[12]={31,28,31,30,31,30,31,31,30,31,30,31}; int k; char tmp[4]; printf("カレンダーを表示します。\n"); printf("開始年月を入力せよ。\n"); printf("年:"); scanf("%d",&nen1); printf("月:"); scanf("%d",&tuki1); printf("終了年月を入力せよ。\n"); printf("年:"); scanf("%d",&nen2); printf("月:"); scanf("%d",&tuki2); do{ /*3つのカレンダー分の格納する*/ for(i=0;i<3;i++) { w=getyoubi(nen1,tuki1,1); sprintf(sbuf[i][0],"%10d /%3d ",nen1,tuki1); for(k=1;j<7;k++) { sbuf[i][k][0]='\0'; } sprintf(sbuf[i][1],"%*s",3*w,""); k=1; for(j=1;j<tuki[tuki1];j++) { sprintf(tmp,"%3d",j); strcat(sbuf[i][k],tmp); if(j%7==6) { k++; } } do{ if(j%7==6) { sprintf(sbuf[i][k],"%21s",""); } else { do{ strcat(sbuf[i][k]," "); j++; }while(j%7!=6); k++; } }while(k!=7); tuki1++; if(tuki1==13) { tuki1=1; nen1++; } if(nen1>nen2 || nen1==nen2 && tuki1>tuki2) { break; } } /*3つためたカレンダーを出力する。*/ for(i=0;i<3;i++) { printf("%s",sbuf[i][0]); } printf("\n"); for(i=0;i<3;i++) { printf(" 日 月 火 水 木 金 土 "); } printf("\n"); for(i=0;i<3;i++) { printf("----------------------"); } printf("\n"); for(i=1;i<7;i++) { for(j=0;j<3;j++) { printf("%s",sbuf[j][i]); } } /*指定した年の月になるまでループ*/ }while(nen1<nen2 || nen1==nen2 && tuki1<=tuki2); return 0; }

  • 入力エラーの処理について。

    Cプログラム初心者です。 例えば、floatの名前をlengthとして、scanfでユーザーに入力させるとします。その時ユーザが間違えて数字ではなく文字を入力した場合、その後のprintfの内容がループしてしまいます。どうしたら、ユーザーが間違えて入力したときに、入力ミスを伝え、もう一回入力をしてもらうことができるプログラムが作れるでしょうか。 以下がエラー処理をする前のプログラムの一部なのですが、、、。 float length; printf("Enter length of the room in metre and press enter.\n"); scanf("%f", &length); while (length>300) { printf("This programme only caluculate length under 300m.\n"); printf("Please re-enter the length in metre and press enter.\n"); scanf("%f", &length); }/*End of while (length)*/

  • エラーの原因がわかりません。

    #include <stdio.h> int bonus(int year,char rank); main() { int a; char s[2]; while(1) { printf("勤続年数:"); scanf("%d",&a); printf("ランク:"); scanf("%s",s); if(bonus(a,s[0])==-1){ exit(1); } if(bonus(a,s[0])==0){ printf("入力エラー\n"); } printf("ボーナス支給額=%d\n",bonus(a,s[0])); } } int bonus(int year,char rank) { int bonus; if(strcmp(rank,'a')==0) if(year<=5) bonus=80000*2.3+80000*3+10000; else if(year<=10) bonus=100000*2.3+100000*3+12000; else if(year<=15) bonus=120000*2.3+120000*3+15000; else if(year>=16) bonus=150000*2.3+150000*3+18000; else return -1; else if(strcmp(rank,'e')==0) return -1; else return -1; return bonus; } 勤続年数とランクを入力したらボーナス支給額を表示させるというプログラムです。 ランクがA,B,C,Dとありましたが、800字以上になるので省略しました。 とりあえずコンパイルできたものの、実行してランクを入力したらエラーが出て終了してしまいます。 そのエラーの原因がわかりません。 多分メモリーら辺がおかしいみたいなんですけど・・・。 よろしくお願いします。

  • 入力値のチェック(西暦、万年カレンダ)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お願いします。 @@@@@ ↑のプログラムがすべて左よりになってしまったのですが、どうすれば段差をつけれますか?

  • scanf()で、エラー対応

    scanf()を使用して、入力で例えば「5462fa」数字ではなく文字を入力してしまった場合エラー(無限ループ)になりますが、 これをscanf()を使用したまま再入力を促すことが可能でしょうか?よろしくお願いします。 #include <stdio.h> int main(){   int a , kazu;   for(a=0;a<1;){     printf("値入力せよー>");       scanf ("%d", &kazu);         if( kazu >= 1 && kazu <=100 ){           a = a + 1 ;         }else{           printf("1から100で入力せよ\n");         }   }   printf ("kazu = %d", kazu);   return 0; }

専門家に質問してみよう