- 締切済み
ヒントを教えて欲しいです
C言語でヒントを教えて欲しいです。 C言語初心者です。 短縮できるとこを教えてほしいです。 キーボードから一文字入力し、それが特殊記号(空白や&等)であればPrintable Symbol、数字であればNumber、大文字の英字であればUpper-case Letter、小文字の英字であればLower-case letterと表示し、それ以外の場合はOthersと表示するプログラムを書け。 #include<stdio.h> main() { char a; printf("Enter a letter:"); scanf("%c",&a); if((a>=32&&a<=47)||(a>=58&&a<=64)||(a>=91&&a<=96)||(a>=123&&a<=126)) printf("Printable Symbol\n"); else if((a>=48&&a<=57)) printf("Number\n"); else if((a>=65&&a<=90)) printf("Upper-case Letter\n"); else if((a>=97&&a<=122)) printf("Lower-case letter\n"); else printf("Other\n"); }
- みんなの回答 (7)
- 専門家の回答
みんなの回答
- Tacosan
- ベストアンサー率23% (3656/15482)
「教える方に問題があるかも」って, 思ってても言わなかったのに....>#4. なお, #3 で「Printable Symbol は最後にチェックすべし」と書いたのは, #6 の最初のプログラムの形を想定しています. Printable Symbol に対する条件が簡単になってるでしょ? char が 8ビットである環境限定の冗談ネタとしては static const char *PrintableSymbol = "Printable Symbol"; static const char *Number = "Number"; // 大文字と小文字は省略 static const char *types[128+256] = { [128+' '] = PrintableSymbol, // ... [128+'0'] = Number, [128+'1'] = Number, // ... [128+'a'] = LowerCase, // 以下略 }; とやると char *type = types[128+ch]; printf("%s\n", type ? type : "Other"); の 2行で終わる. #5 以上に行数を食う (かつデータを入れ忘れると間抜け) のが問題だけど.
- titokani
- ベストアンサー率19% (341/1726)
「短縮」というところに話を絞ると、 #include<stdio.h> main() { char a; printf("Enter a letter:"); scanf("%c",&a); if( a >= 48 && a <= 57 ){ printf("Number\n"); }else if( a >= 65 && a <= 90 ){ printf("Upper-case Letter\n"); }else if( a >= 97 && a <= 122 ){ printf("Lower-case letter\n"); }else if( a >= 32 && a <= 126 ){ printf("Printable Symbol\n"); }else{ printf("Other\n"); } こういうことなのかな。 あるいは、 main() { char a; printf("Enter a letter:"); scanf("%c",&a); if( a >= 32 && a <= 126 ){ if( a >= 48 && a <= 57 ){ printf("Number\n"); }else if( a >= 65 && a <= 90 ){ printf("Upper-case Letter\n"); }else if( a >= 97 && a <= 122 ){ printf("Lower-case letter\n"); }else{ printf("Printable Symbol\n"); } }else{ printf("Other\n"); } こうとか。 文字コードとかそういった話を抜きにして、単純にif文の学習だとするなら、これもありかと。
補足
Printable Symbolを最後にして範囲を短縮させたんですね! 参考にさせていただきました。
こんにちは。 ASCIIコード限定ですが、is~系の関数を使用しないサンプルを作ってみました。 ※ご提示のプログラムよりもコード量が多くなってしまいましたが。。。 ※ご使用の環境で、上手くビルド&実行できなかった場合はすみません。 参考になれば幸いです。 ■サンプルプログラム 注1)「制御文字」or「ASCIIコード以外」の判定の部分のみ固定コードを使用 しています。 注2)インデントなどのため、全角スペースを入れています。 ご使用の際は、半角スペースorタブに置換して下さい。 ========================= /* * CodeCheck.c : 文字種別判定(サンプル) */ #include <stdio.h> /* 文字種別の定義 */ enum E_TYPE { TYPE_NUMBER, /* 0:数字 */ TYPE_ALF_UPPER, /* 1:英大文字 */ TYPE_ALF_LOWER, /* 2:英小文字 */ TYPE_SEP1, /* 3:区切り値 */ TYPE_SYMBOL = TYPE_SEP1, /* 3:印刷文字 */ TYPE_OTHER, /* 4:その他 */ TYPE_MAX /* 5:区切り値(最大値) */ }; int main(void) { int cnt; /*ループ用*/ int nType; /*文字種別*/ char cKey; /*入力文字*/ const char *p1; /*文字テーブルのアクセス用*/ /* 数字、英字の文字テーブル */ const char szCodeTbl[TYPE_SEP1][32] = { { "0123456789" }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, { "abcdefghijklmnopqrstuvwxyz" } }; /* 出力メッセージテーブル */ const char szCodeName[TYPE_MAX][32] = { { "Number" }, { "Upper-case Letter" }, { "Lower-case Letter" }, { "Printable Symbol" }, { "Others" } }; /* 文字の入力 */ printf( "Enter a letter:" ); scanf( "%c", &cKey ); /* 入力文字が「数字or英字」かの判定 */ nType = -1; for( cnt=0; nType<0 && cnt<(int)TYPE_SEP1; cnt++ ){ p1 = szCodeTbl[ cnt ]; while( *p1!='\0' ){ if( cKey == *p1 ){ nType = cnt; break; } p1++; } } /* 入力文字が「数字or英字」以外の時の判定 */ if( nType<0 ){ if( cKey<0x20 || cKey>0x7e ){ /*「制御文字」or「ASCIIコード以外」*/ nType = (int)TYPE_OTHER; } else{ /*「印刷文字」*/ nType = (int)TYPE_SYMBOL; } } /* 判定結果の出力 */ printf( "%s\n", szCodeName[nType] ); return 0; } =========================
補足
ありがとうございます。 見たことのないものばかりでさっぱりわかりませんが… 参考にさせていただきます。
- Wr5
- ベストアンサー率53% (2173/4061)
>それで明らかにネットで調べました、みたいなのはどうかと思ったのです。 安易に勝ち組(課題丸投げ)に行かない姿勢はよいかと思われます。 説明不足に関しては仕方ないですが。 しかし… >講義で作ったプログラムも文字定数を使わずに48とかを使っていたのでここでも使いました。 というのは……#3さんの意見に賛成…ですね。 講義を行っている方にも問題があるような気がしてなりません。 そこで習っていて、将来的にどうなのか不安ですね…。 「入門者に文字定数なんて教えても解らん」とか思っているのでしょうか……。 入門向けだとエラー処理が省かれたりすることはよくありますけど…。 やはり、is~系が王道。でしょう。 教えていないモノ使ったから減点。とかいう出題者であれば、これから先を考えた方がいいかもしれません。 # 教えている相手が小学校低学年でもあるまいし。 ……アリエナイ書き方として、switch~caseなんて手もありますね。 私が出題者なら減点ものですが。 switch(a) { case '0': (中略) case '9': printf("Number\n"); break; (中略) default: printf("Other\n"); break; }
補足
返事が遅くなってしまい申し訳ありません。 >安易に勝ち組(課題丸投げ)に行かない姿勢はよいかと思われます。 自分でやらないと意味がないと思ったので。 自分が聞き逃した可能性もあったのでプログラミングが詳しい友人に聞いたらやっぱり文字定数はやっていないそうです。 >やはり、is~系が王道。でしょう。 ネットで調べてみます。 >……アリエナイ書き方として、switch~caseなんて手もありますね。 そういう物もあるんですね… 正直ほとんどの物を初めて見るのでさっぱりわかりません。 多少こんがらがってきてます…
- Tacosan
- ベストアンサー率23% (3656/15482)
「文字定数を使わない」プログラムを使うだなんて.... とてもじゃないが信じられない. 「教える人間が必ずしも問題を認識しているとは限らない」んだけど, だからといってそれはかなりどうかと思う. さておき, 「最も短く最も安全」なのは isXXX 系です. それが使えない場合, 「使っている環境」 (というか「使っている実行系の文字コード」) を仮定していいかどうかに強く依存します. 例えば ASCII を仮定していいなら ・ch が大文字 if and only if 'A' <= ch && ch <= 'Z' といえるので簡単. そうじゃないと, EBCDIC のように「アルファベットが連続しない」ことも想定できるので, あきらめて ch == 'A' || ch == 'B' || ... || ch == 'Z' と書くしかない. ちなみに Printable Symbol は最後にチェックすべし.
補足
よくわかんないですけど… 簡略化をしたほうがミスも少なくなるし見やすいのでしたほうが良いのですね。 Printable Symbolに間違いがありましたか…? 見つからなくて…
- Wr5
- ベストアンサー率53% (2173/4061)
>isdigitは習っていないのでわかりません。 だったらリファレンスくらい引きましょう。 これから先、「習ったモノだけ」使ってプログラミングしていくつもりですか? 標準関数をすべて習って…仕事で入ったところではライブラリ関数も一から先輩に習うつもりですか? # 学生の課題では自分でリファレンス引いてはいけない制限があるのが普通なんですか? # 英文の翻訳するのに英和辞書の使用は禁止。っていう英語の授業みたいですね。 パッと見でわかりにくい数字(マジックナンバー)を使うのは避けましょう。 3週間後の自分が見て、「48ってなに?」とかになりますよ。 isなんちゃら系が無理でも… >else if((a>=48&&a<=57)) は >else if((a>='0'&&a<='9')) と文字定数で書けます。 >if((a>=32&&a<=47)||(a>=58&&a<=64)||(a>=91&&a<=96)||(a>=123&&a<=126)) は難しい部分もありますが…
補足
確かに中学生みたいなことを言いました。 説明も足りなかったですし。 詳しく言いますと大学のC言語入門のような講義の課題なんです。 それで明らかにネットで調べました、みたいなのはどうかと思ったのです。 講義で作ったプログラムも文字定数を使わずに48とかを使っていたのでここでも使いました。
- asuncion
- ベストアンサー率33% (2127/6289)
32とか47とかいう、特定の文字コードに依存するソースコードは あまりよろしくないです。 文字種を判定するために、「isなんとか」系の関数またはマクロを 標準で用意しています。そういうのをお使いになる方が、 何をしているソースコードであるかがわかりやすいと思います。 例:数字かどうかを判定する関数(またはマクロ)はisdigit
補足
isdigitは習っていないのでわかりません。
補足
問題文にとらわれていました。 よく考えないといけないことがわかりました。 やり方としてはいろいろあるのですね… わかんないですけど…