- ベストアンサー
関数がうまく動作しない
関数get_monthにchar *型の文字列を引数にして、先頭の三文字(大文字でも小文字でも可)が正しいかどうかを関数strnxcmpでチェックしていくものです。 ところが、関数get_month中のreturn iで帰ってくるのはメインプログラムを動作させたところいつも0になってしまっているようです。(本当は1~12が帰ってくるようにしたい。) for(i=1;i<=12;i++) { if(strnxcmp(tuki[i],s,3)==0) { return i;←ここのリターンで0が帰ってきてしまう。 } } } 何がおかしいためにこのようになってしまうのでしょうか? よろしくお願いします。 int strnxcmp(const char *s1,const char *s2,size_t n) { while(n && toupper(*s1) && toupper(*s2)) { if(toupper(*s1) != toupper(*s2)) { return ((unsigned char)*s1 - (unsigned char)*s2); } s1++; s2++; n--; } if(!n)return 0; if(*s1) return 1; return -1; } int get_month(char *s) { int m,i; char *tuki[]={"","January","Feburary","March","April","May","June","July","Augst", "September","October","November","December"}; for(i=1;i<=12;i++) { if(strnxcmp(tuki[i],s,3)==0) { return i; } } return -1; }
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
こだわっていますよね。だからあなたの主義を尊重し、ちょっとだけ変えてみました。最初見たとき何がなんだかわかりませんでした。よは、 ./a.out <janualy <2010>> 風にパラメータを与えてカレンダーを起動・表示することを考えられていたんですね。 #include<stdio.h> #include<time.h> #include<stdlib.h> #include<ctype.h> int tuki[12]={31,28,31,30,31,30,31,31,30,31,30,31}; /* *si: tuki[i] *s2: argv[1] size_t:3 */ int strnxcmp(char *s1, char *s2, size_t n) { while(n && *s2) { // 比較の文字があること if(toupper(*s1) != toupper(*s2)) // 大文字変換した字が違う return -1; s1++; s2++; n--; } if (!n) return 0; // 該当あり if (*s1) return 1; // 字余り return -1; // その他 } int get_month(char *s) { int m,i; char *tuki_name[]={"","January","Feburary","March","April","May", "June","July","Augst","September","October","November","December"}; for(i=1;i<=12;i++) { if(strnxcmp(tuki_name[i],s,3)==0) { printf("strxcmp(%s)= %d\n", s, i); // ←追加 return i; } } return -1; } void put_calendar(int year, int month) { int tukisai,i,tukiho; tukisai=tuera(year,month,1); printf("%*s",3*tukisai,""); if (month==2 && (year%4==0 && year%100!=0 || year%400==0)) tukiho=tuki[1]+1; else tukiho=tuki[month-1]; for(i=1;i<=tukiho;i++) { printf("%3d",i); if((i+tukisai)%7==0) printf("\n"); } printf("\n"); // ←追加 } int tuera(int ye,int mon,int da) { if(mon==1 || mon==2 ) { ye--; mon +=12; } return (ye+ye/4-ye/100+ye/400+(13*mon+8)/5 + da)%7; } int main(int argc,char *argv[]) { int m, y; time_t t; struct tm *local; t = time(NULL); local = localtime(&t); y=local->tm_year+1900; m=local->tm_mon+1; if(argc==3) { y=atoi(argv[2]); if(y < 0) { fprintf(stderr,"年の値が不正です。\n"); return 0; } } if(argc>=2) { m=get_month(argv[1]); // argv[1]に英字月が入っている? if(m<0 || m>12) { fprintf(stderr,"月の値が不正です。\n"); return 0; } } printf("%d年%d月\n\n",y,m); printf(" 日 月 火 水 木 金 土 \n"); printf("----------------------\n"); put_calendar(y,m); return 0; }
その他の回答 (7)
- mistmoon79
- ベストアンサー率50% (2/4)
書き間違えた if(m>=1 && m<=12)
- mistmoon79
- ベストアンサー率50% (2/4)
#2補足を見て思ったんだけど xxx.exe jan 見たいな入力だけじゃなく xxx.exe 1 のような入力にも対応させたいんですかね? だとすれば if(m>=1 || m<=12) はおかしいよね。 if (m>= && m<=12) だと思うよ。
- koi1234
- ベストアンサー率53% (1866/3459)
#3補足 #3で書いたのは質問文に書いてる関数での話 #2さんの補足にある関数では int get_month(char *s) { m=atoi(s); if(m>=1 || m<=12) { return m; } これで0返るでしょう ってか質問文とやってることがぜんぜん変わってるし
- SilverThaw
- ベストアンサー率32% (260/806)
#1返答 >ループの中に、returnを入れると動作しないんですね。 >ですが、なぜか私の環境では普通に動作をしているようです。 いいえ。returnは動作します。 言い方は悪いですが、「汚いソース」だというだけです。 最初に引数のチェック等でエラーをチェックするような場合、途中でのrteurnはソースの可読性を悪くするだけです。 #2返答 >コマンドライン引数の2文字目でaugやaprなどを引数として >渡しましたが、0月と表示されてしまいます。 当然の動作です。 そもそも、「どこまで動作しているのか」ということを確認もせずに結果だけから判断し、 尚且つ「間違った『推測』」で問題箇所を判断しているのですから何時まで経っても解決しないでしょう。 >m=get_month(argv[1]); この時、get_month()に渡しているargv[1]の内容は何ですか? >int get_month(char *s) >{ >(中略) >m=atoi(s); >if(m>=1 || m<=12) >{ >return m; >} atoi()は「何を行う」関数ですか?
- koi1234
- ベストアンサー率53% (1866/3459)
全体ちゃんと見てませんが#2さんもかかれてますが ソース的にget_month関数が0を返すことがありえません 他の部分が間違っているはずです(見当違いの原因を探してます) またfor文の中でreturn関数使っても何も問題はありません (その人のコーディングスタイルだけの問題)
- mistmoon79
- ベストアンサー率50% (2/4)
0が帰ってきていることをどうやって確認しましたか? 私が提示の関数を使用してテストプログラムを作ってみましたが問題なく1~12が帰ってきましたよ。 確認方法が間違っているんじゃないでしょうか?
- kopanda116
- ベストアンサー率37% (88/232)
nt get_month(char *s) { int m,i; char *tuki[]={"","January","Feburary","March","April","May","June","July","Augst", "September","October","November","December"}; for(i=1;i<=12;i++) { if(strnxcmp(tuki[i],s,3)==0) { return i; ←ここにreturn文があることがオカシイです!! } } return -1; } 普通、return文は、for文の中に書いたりはしません。 それならば、一度、int型の変数を用意しておき、それに上の”return i;”の部分でその配列にiを代入してから、"return -1;"の部分で、returnすればよいと思います。 nt get_month(char *s) { int i; char *tuki[]={"","January","Feburary","March","April","May","June","July","Augst", "September","October","November","December"}; int mon = -1; for(i=1;i<=12;i++) { if(strnxcmp(tuki[i],s,3)==0) { mon =i; } } return mon; } は、どうでしょうか?
お礼
回答ありがとうございます。 ループの中に、returnを入れると動作しないんですね。 ですが、なぜか私の環境では普通に動作をしているようです。 それと、また動作させたところget_month関数に間違った文字列 たとえばfajklfajlsのように月名と全く関係ない文字列を 引数に渡しても全て0が帰ってきてしまうようになりました(涙)
お礼
このプログラムをコンパイラーで動作させて確認しましたが、 コマンドライン引数の2文字目でaugやaprなどを引数として 渡しましたが、0月と表示されてしまいます。 #include<stdio.h> #include<time.h> #include<stdlib.h> #include<ctype.h> int tuki[12]={31,28,31,30,31,30,31,31,30,31,30,31}; int strnxcmp(const char *s1,const char *s2,size_t n) { while(n && toupper(*s1) && toupper(*s2)) { if(toupper(*s1) != toupper(*s2)) { return ((unsigned char)*s1 - (unsigned char)*s2); } s1++; s2++; n--; } if(!n)return 0; if(*s1) return 1; return -1; } int tuera(int ye,int mon,int da) { if(mon==1 || mon==2 ) { ye--; mon +=12; } return ((ye+ye/4-ye/100+ye/400+(13*mon+8)/5 + da)%7); } void put_calendar(int year,int month) { int tukisai,i,tukiho; tukisai=tuera(year,month,1); printf("%*s",3*tukisai,""); if(month==2 && (year%4==0 && year%100!=0 || year%400==0)) { tukiho=tuki[1]+1; } else { tukiho=tuki[month-1]; } for(i=1;i<=tukiho;i++) { printf("%3d",i); if((i+tukisai)%7==0) { printf("\n"); } } } int get_month(char *s) { int m,i; char *tuki[]={"","January","Feburary","March","April","May","June","July","Augst", "September","October","November","December"}; m=atoi(s); if(m>=1 || m<=12) { return m; } for(i=1;i<=12;i++) { if(strnxcmp(tuki[i],s,3)==0) { return i; } } return -1; } int main(int argc,char *argv[]) { int y,mon,h,i; int m; time_t t = time(NULL); struct tm *local = localtime(&t); y=local->tm_year+1900; m=local->tm_mon+1; if(argc>=2) { m=get_month(argv[1]); if(m<0 || m>12) { fprintf(stderr,"月の値が不正です。\n"); return 1; } } if(argc>=3) { y=atoi(argv[2]); if(y<0) { fprintf(stderr,"年の値が不正です。\n"); return 2; } } printf("%d年%d月\n\n",y,m); printf(" 日 月 火 水 木 金 土 \n"); printf("----------------------\n"); put_calendar(y,m); return 0; }