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文できれいに書くような方法はありませんでしょうか?
もしくはこうすればスマートに書けるというようなものがあればお教えください。よろしくお願いします。
No.5ベストアンサー
- 回答日時:
移植性をあきらめるならば,
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'): .....
てな書き方もあり得ますね.
複数文字定数を使うよりこちらの方が行儀がいいとも言えます.
No.7
- 回答日時:
マクロによるものなので、プロジェクト内で使用するのはお勧めしませんが、こんな方法もあります。
>>
#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;
}
}
}
<<
No.6
- 回答日時:
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)の処理系では動作が未定義になります)
No.4
- 回答日時:
え~と, 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);
}
のようにしてしまう手もある. 無名関数が使えれば (ある意味) 完璧なんだけど.
No.3
- 回答日時:
検索したい文字列の長さが固定で,4バイト(intのバイト長)以下なら,switch文でできなくもないです.2バイト固定長だとすると.
switch(( no[0]&0xFF) | (no[1]<<8)&0xFF00) {
case '10': ...
case '20': ...
}
'20'と言う書き方はバイトオーダーの問題が生じるので,アスキーコード表を引いて
case 0x3230 :
とするほうがいいかもしれませんが.
読みにくいプログラムになるので,後の保守のためにコメントを適切に入れておく必要があります.
ありがとうございます。
case '20':というふうに書けるならば望みどおりなのですが、case 0x320x30という記述をしなければならないのなら確かに少し観にくいですね。とにかくnoが”10”ならば処理1、”20”ならば処理2っていうのが観てわかりやすい書き方を考えています。どうしてもif文で条件にstrncmpとかの式を書くと観にくいので。
No.2
- 回答日時:
文字列のテーブルを検索すればできます。
-- 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;
}
ありがとうございます。
確かにswitch文でかけますが、判断する2byte文字列を追加する場合に、indexとswitch文を両方メンテしなければならなので、少し使いにくいと思いました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語:数値の桁数指定についての質問です。 8 2022/05/26 23:53
- その他(プログラミング・Web制作) 単純なコマンドプロンプトが動きません。 2 2022/04/19 15:21
- PHP PHPの変わった閉じタグの必要性と意味を教えてください。 1 2022/08/28 15:15
- Visual Basic(VBA) この関数と同じ処理をVBAで行うにはどうしたら良いでしょうか? これは、1列の中に同じ値が複数存在し 21 2022/07/07 07:48
- Visual Basic(VBA) vbaのループ処理について 6 2022/05/06 15:35
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Visual Basic(VBA) エクセルのマクロで対象ごとにシート分けしてその内容をセルに書き込みたい 9 2022/08/24 13:23
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- Visual Basic(VBA) VBAのトグルボタンでのマクロについて質問です 3 2022/10/10 17:23
- Excel(エクセル) B列に文字がはいったらA列に数字が入るマクロードを完成させたい 4 2023/04/21 01:58
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CStringをwchar_tに変換したい
-
ネットワークにつながっている...
-
文字列から空白を取り除きたい...
-
配列をnビットシフトする
-
バイナリファイルをコピーする...
-
iconv_open失敗
-
100バイトのバイナリファイルを...
-
C言語 バイナリファイルをfloa...
-
C言語です
-
atoi( ) の反対をやりたい
-
VC++でコンパイルエラーが出ま...
-
2曲同時再生するにはどうした...
-
char型の扱える範囲とは?
-
'const char *' 型は 'char *' ...
-
main の引数には const 付けた方が
-
引数の渡し方と受け方(argv)
-
ひとつのプログラムにしたいの...
-
c#でbmp画像の上下反転
-
c言語の問題の説明、各所ごとに
-
_TCHAR*での引数の読み込み
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【至急】C言語の問題です、どな...
-
charからLPTSTRへの変換方法
-
charでの計算?
-
配列をnビットシフトする
-
fgetsなどのときのstdinのバッ...
-
絶対パスからのファイル名の切...
-
文字列から空白を取り除きたい...
-
C言語のfor文です。 繰り返しの...
-
テキストデータをそのままバイ...
-
CStringをwchar_tに変換したい
-
switch文で文字を比較すること...
-
C言語の入力した文字を反転させ...
-
atoi( ) の反対をやりたい
-
double型の値をchar配列に変換...
-
C言語 ミリ秒を日付に変換には
-
'const char *' 型は 'char *' ...
-
文字列がNULLか空文字列かの判定
-
c++ 文字列を入力して、一文字...
-
型変換
-
干支のプログラム
おすすめ情報