こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

数字と、文字列入力のチェックを同時にする方法

 最近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がありましたら教えて下さい。

宜しくお願いします。

投稿日時 - 2004-07-17 22:54:43

QNo.930166

暇なときに回答ください

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

スッキリ解決する方法、あります。
【正規表現】です

まず結論から…
質問内容を正規表現で表現するとこんな感じでしょうか…
"[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 で「正規表現とは」などのキーワードで検索すればもっと詳しいことがわかります。

投稿日時 - 2004-07-18 01:19:55

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

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.単位部があれば内容をチェック。その際、配列を使うことで処理を簡素化

コンパイルしてません。

投稿日時 - 2004-07-19 13:39:25

ANo.4

#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等の入力で小文字入力される可能性があるのでこのチェックもしておいた方がいいですね。

頑張って下さい。

投稿日時 - 2004-07-18 02:28:02

ANo.3

正規表現だと ([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 */
}

とかでしょう。

投稿日時 - 2004-07-18 02:01:28

ANo.2

ちょっと間違えました。
誤 "[0-1]+[KMGkmb]?[Bb]?"
正 "[0-9]+[KMGkmg]?[Bb]?"

かな。
また、この表現だと
>・0だけ入力は認めない。
には対応してません

投稿日時 - 2004-07-18 01:24:58

あなたにオススメの質問