プロが教える店舗&オフィスのセキュリティ対策術

2バイトの文字列の中身によって違う処理をするプログラムを作成しています。
数値ならば、
switch(no){
case 10:
処理1
break;
case 20
処理2
break;



}
と書けるのですが、文字列だと
if(strncmp(no,"10",2) == 0){
<処理1>
}else if(strncmp(no,"20",2) == 0){
<処理2>
}else if



}
というような書き方しか分かりません。数値同様にswitch文できれいに書くような方法はありませんでしょうか?
もしくはこうすればスマートに書けるというようなものがあればお教えください。よろしくお願いします。

A 回答 (8件)

移植性をあきらめるならば,



case'10'と 書いて動くようにswitch文を工夫すればよいです.

i386なら,これで動くはず.
switch(( no[1]&0xFF) | (no[0]<<8)&0xFF00) {
case '10': ...

bigndianのSokaris/sparcでもこれで動きます.

メインフレームのCコンパイラの中には,
switch(( ( no[0]<<24)&0xFF000000) | (no[1]<<16)&0xFF0000) {
case '10': ...
でうごく変な奴も居ますが.
あと,文字定数の中に複数文字入れるとコンパイラがwarningを出すと思います.

さもなくば,
#define char2short(a,b) (( b&0xFF) | (a<<8)&0xFF00)
switch(char2short( no[0],no[1]) ){

case char2short('1', '0'): .....
case char2short('2', '0'): .....

てな書き方もあり得ますね.
複数文字定数を使うよりこちらの方が行儀がいいとも言えます.
    • good
    • 0
この回答へのお礼

2番目のやり方が一番良いと思いました。ありがとうございました。

お礼日時:2006/04/11 09:09

文字列が数字だけと決まっているのならばatoiとか


boost::lexical_cast(C++の場合)などで数値に返還してからswitchすればよいと思います。

数字だけじゃない場合はだめなので自信なしです。
    • good
    • 0
この回答へのお礼

#5のやり方でいこうと思います。ありがとうございました。

お礼日時:2006/04/11 09:12

マクロによるものなので、プロジェクト内で使用するのはお勧めしませんが、こんな方法もあります。



>>
#include <stdio.h>
#include <string.h>

#define strswitch(s) { char* __s__ = s; if (0)

#define strcase(t) } else if (strcmp(t, __s__) == 0) {

#define strdefault } else

#define strbreak

int main() {
char s[BUFSIZ];

while (fgets(s, BUFSIZ, stdin)) {
s[strlen(s) - 1] = '\0';
strswitch(s) {
strcase("12")
printf("12OK\n");
strbreak;
strcase("34")
printf("34OK\n");
strbreak;
strcase("56")
printf("56OK\n");
strbreak;
strdefault
printf("defaultOK\n");
strbreak;
}
}
}
<<
    • good
    • 0
この回答へのお礼

参考になりました。ありがとうございました。

お礼日時:2006/04/11 09:11

2バイトと分かっているのであれば、#5の方が提案されている



> #define char2short(a,b) (( b&0xFF) | (a<<8)&0xFF00)
> switch(char2short( no[0],no[1]) ){
>
> case char2short('1', '0'): .....
> case char2short('2', '0'): .....

という書き方が一番よいと思います。
ただし移植性と安全性を考慮するなら、もう一工夫して、

#include <limits.h>
#define char2word(a,b) ((unsigned char)(b) | ((unsigned char)(a)<<CHAR_BIT))

とした方がよいでしょう。
(ただし、上記の書き方をしても、sizeof(char)==sizeof(int)の処理系では動作が未定義になります)
    • good
    • 0
この回答へのお礼

私も#5のやり方が良いと思いました。ありがとうございました。

お礼日時:2006/04/11 09:10

え~と, switch を捨ててしまうという方針もあるかと.


例えば,
struct Item {
char *name;
void (*op)(const char *name);
};
という構造体を用意して, その配列を
Item tbl[] = { { "10", func1 }, { "20", func2 }, ..., { NULL, NULL } };
と作って,
Item *p;
for (p = tbl; p->name != NULL; ++p) {
if (!strcmp(no, p->name)) {
break;
}
}
if (p->name) {
p->op(p->name);
}
のようにしてしまう手もある. 無名関数が使えれば (ある意味) 完璧なんだけど.
    • good
    • 0
この回答へのお礼

返事がおそくなり申し訳ございません。参考になりました。

お礼日時:2006/04/11 09:07

検索したい文字列の長さが固定で,4バイト(intのバイト長)以下なら,switch文でできなくもないです.2バイト固定長だとすると.



switch(( no[0]&0xFF) | (no[1]<<8)&0xFF00) {
case '10': ...
case '20': ...
}

'20'と言う書き方はバイトオーダーの問題が生じるので,アスキーコード表を引いて
case 0x3230 :
とするほうがいいかもしれませんが.

読みにくいプログラムになるので,後の保守のためにコメントを適切に入れておく必要があります.
    • good
    • 0
この回答へのお礼

ありがとうございます。
case '20':というふうに書けるならば望みどおりなのですが、case 0x320x30という記述をしなければならないのなら確かに少し観にくいですね。とにかくnoが”10”ならば処理1、”20”ならば処理2っていうのが観てわかりやすい書き方を考えています。どうしてもif文で条件にstrncmpとかの式を書くと観にくいので。

お礼日時:2006/04/07 14:28

文字列のテーブルを検索すればできます。


-- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --
#include <stdio.h>
#include <string.h>
int
main(void)
{
char buf[BUFSIZ];
char *index[] = {"ab", "cd", "ef", NULL};
int i;

fprintf(stderr, "二文字入力してね >> ");
fgets(buf, BUFSIZ, stdin);

for (i = 0; index[i] != NULL; i++) {
if (strncmp(buf, index[i], 2) == 0) {
break;
}
}

switch (i) {
case 0:
printf("abです。\n");
break;
case 1:
printf("cdです。\n");
break;
case 2:
printf("edです。\n");
break;
default:
printf("その他です。\n");
}
return 0;
}
    • good
    • 0
この回答へのお礼

ありがとうございます。
確かにswitch文でかけますが、判断する2byte文字列を追加する場合に、indexとswitch文を両方メンテしなければならなので、少し使いにくいと思いました。

お礼日時:2006/04/07 14:21

C言語はswitch文に文字列を指定することはできません。


従って質問者さまのようにif文でやることになります。
    • good
    • 0
この回答へのお礼

ありがとうございます。
if~else ifとかを使って書くと観にくいので、観やすい書き方を探しています。

お礼日時:2006/04/07 14:17

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!