- ベストアンサー
数字と、文字列入力のチェックを同時にする方法
最近Cを勉強しはじめたものです。 文字列のチェックでどうしていいのかわからないので アドバイス下さい! ユーザからデータのサイズ入力を求めた後、入力された数字と、文字列入力のチェックをしたいのです。考えてることはこうです。 (1)ユーザにデータのサイズ入力を求める。 (2)ユーザはサイズを入力する。 この時、認められている入力形式は ・100 ・100B ・100M ・100MB のような4パターンの入力が可能。 (ちなみにMだけでなく、K、Gも可能にできるように考えています。) (3)この入力された文字列をチェックする。 ・0だけ入力は認めない。 ・数字とK、M、G、B、KB、MB、GBの組み合わせはOKそれ以外の文字や文字列は認めない。 ・100MBはOKだが、M100BやMB100などは認めない。 とすると、一つ一つチェックしていくと ソースの階層がどんどん深くなっていく気がして 混乱しています。 どのようにすればスッキリできるでしょうか? また、このような文字列比較ができる関数やAPIがありましたら教えて下さい。 宜しくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
スッキリ解決する方法、あります。 【正規表現】です まず結論から… 質問内容を正規表現で表現するとこんな感じでしょうか… "[0-1]+[KMGkmb]?[Bb]?" ですのでこれとマッチしてるかどうかをチェックするだけですので、正規表現の1ステップと if文の1ステップだけでチェック完了させることができます。すばらしいでしょ? 正規表現というのを分かり易く言うと、文字列のパターンの表現方法のことで、あなたがやりたいようなこととピッタリあいます。 正規表現ではないですが Windowsだと dosプロンプトなんかで dir *.txt とか del aaa??.dat とかって 「*」や「?」を使った表現をやりますよね?あれをもっと汎用的に拡張したものです。 ただし言語によって準備されているライブラリの状況が異なります。 ★ Java の場合 JDK1.4 で標準で用意されてます。 ★ C++ の場合 標準で用意されてません。以下のライブラリが使えます。 http://www.boost.org/ ★ C の場合 標準で用意されてません。 これは使ったことないですが、以下で発見しました。 http://www.sip.eee.yamaguchi-u.ac.jp/kou/regex.html おそらくあなたが質問した内容だと一発でチェックできると思われます。最近Cを始めたということなので敷居は高いかもしれませんが、こういうのがあるという事は覚えておいてください。今回は使わなかったとしても将来は役に立つと思われます。 Yahoo! や Google で「正規表現とは」などのキーワードで検索すればもっと詳しいことがわかります。
その他の回答 (4)
- toysmith
- ベストアンサー率37% (570/1525)
struct { char ss[4] ; long long vv ; } arry[] = { { "B", 1LL }, { "K", 1024LL}, {"KB", 1024LL }, { "M", 1024LL * 1024LL }, {"MB", 1024LL * 1024LL }, { "G", 1024LL * 1024LL * 1024LL}, {"GB", 1024LL * 1024LL * 1024LL}} ; val = strtol(input, &endptr, 10) ; if (*endptr != NULL) { for (ii 0 ; ii < (sizeof(arry) / sizeof(arry[0])) ; ii++) { if (strcmp(endptr, arry[ii].ss) == 0) { break ; } } if (ii == (sizeof(arry) / sizeof(arry[0]))) { /* 単位がおかしい */ } lval = val * arry[ii].vv ; } else { lval = val ; } 1.strtolで数値変換をしながら単位部の有無をチェック 2.単位部があれば内容をチェック。その際、配列を使うことで処理を簡素化 コンパイルしてません。
- Tsukasa0215
- ベストアンサー率22% (280/1257)
#include <stdio.h> #define MAX_STR 19 char errchk(char *str) { char flg=0; while(*str!=NULL){ switch(*str) { case '9': case '8': case '7': case '6': case '5': case '4': case '3': case '2': case '1': if(flg>1) return(0); flg=1; case '0': if (flg!=1) return(0); break; case 'K': case 'k': case 'M': case 'm': case 'G': case 'g': if(flg!=1) return(0); flg=2; break; case 'B': case 'b': if((flg==2)||(flg==1)) { flg=3; break; } default: return(0); } str++; } return (flg); } void main(void) { char str[MAX_STR][15]={ "100", "100B", "100M", "100MB", "100K", "100KB", "100M", "100MB", "0", "K0B", "010B", "10TB", "M10B", "MB10", "10KB 100KB", "10BK", "10BB", "10KK", "10MK", }; char i,errf; for(i=0;i<MAX_STR;i++){ errf=errchk(str[i]); printf("%2d:'%s':",i+1,str[i]); if (errf) printf("OK!\n"); else printf("NG!\n"); } } 独自処理する場合、自分で関数を作りましょう! ここでは毎回入力するのは面倒だったので、テストパターンの配列にしていますが、実際には入力ルーチンに変更して下さい。 KBやMB等の入力で小文字入力される可能性があるのでこのチェックもしておいた方がいいですね。 頑張って下さい。
- nyan5504
- ベストアンサー率42% (6/14)
正規表現だと ([1-9]|[1-9][0-9]+)[GMKgmk]?[Bb] でしょうねえ。 Cで無難にやるなら int size; char unit[16]; sscanf("100MB","%ld%s",&size,unit); if(!stricmp(unit,"GB")) { } else if(!stricmp(unit,"MB")) { } else if(!stricmp(unit,"KB")) { } else if(!stricmp(unit,"B")) { } else { /* error */ } とかでしょう。
- SpiralGalaxy
- ベストアンサー率39% (649/1653)
ちょっと間違えました。 誤 "[0-1]+[KMGkmb]?[Bb]?" 正 "[0-9]+[KMGkmg]?[Bb]?" かな。 また、この表現だと >・0だけ入力は認めない。 には対応してません