![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
いつも丁寧な解説拝見しております。
C言語について質問させて頂きます。
シリアル通信によって受信した1バイトの文字列があるとします。
この文字列のパターンよって処理の分岐をさせたい場合、コードはどのように書けば良いのでしょうか。
より具体的に申しますと、
→文字列パターン1の場合、関数1を呼び出す。
→文字列パターン2の場合、関数2を呼び出す。
→文字列パターン3の場合、関数3を呼び出す。・・・・・・
と、100パターンほどの文字列があり、それぞれにおいて異なる関数を呼び出したいと考えております。私の理解は以下に示す通りなのですが、どうも正しい処理が分らないでいます。
・受信した文字列がどのパターンなのかを判断するために、strcmp関数で比較を行う。
・多分岐なので、switch case文かelse if文を用いる。
この場合、条件式の中でstrcmp関数による比較を行えば良いのでしょうか。簡単にコードを示して頂ければ幸いです。C言語初心者なので理解に間違いがあるかもしれませんが、どうぞよろしくお願い致します。
No.4ベストアンサー
- 回答日時:
文字列の種類が100種類あると、if文の羅列では一回の検索で平均して50回のstrcmp関数を実行する必要があります。
良く出現する文字列の検索を前方におけば回数を少なくすることは可能だと思いますが…。二分検索を行うと最大で7回に抑えることができます。
文字列ポインタと関数ポインタを格納した構造体の配列をqsortで整列させておいて、bsearchで二分検索して一致する文字列があれば対応する関数を実行する感じです。
#include <stdlib.h>
#include <string.h>
#defineN5
struct s {
char*str ;
int (*f)(void) ;
} ;
chars0 [] = "abc" ;
chars1 [] = "de" ;
chars2 [] = "fghi" ;
chars3 [] = "opq" ;
chars4 [] = "jklmn" ;
intf0 (void) {printf ("f0実行\n") ;return 0 ;}
intf1 (void) {printf ("f1実行\n") ;return 0 ;}
intf2 (void) {printf ("f2実行\n") ;return 0 ;}
intf3 (void) {printf ("f3実行\n") ;return 0 ;}
intf4 (void) {printf ("f4実行\n") ;return 0 ;}
struct s st [N] = {
{s0, f0},
{s1, f1},
{s2, f2},
{s3, f3},
{s4, f4},
} ;
intcomp (const void *a, const void *b)
{
return strcmp (((struct s*) a)->str, ((struct s*) b)->str) ;
}
intsearch_do (char *mojiretu)
{
struct ssa,*sp ;
intrtn = 0 ;
sa.str = mojiretu ;
sp = (struct s*) bsearch (&sa, st, N, sizeof (struct s), comp) ;
if (sp != NULL) {
sp ->f () ;
}
else {
printf ("一致文字列なし\n") ;
rtn = 1 ;
}
return rtn ;
}
int main(void)
{
qsort (st, N, sizeof (struct s), comp) ;
search_do ("fghi") ;
search_do ("fgh") ;
return 0;
}
No.3
- 回答日時:
おっと失礼。
バグがありました。printf("%sです。\n");
printf("%sだよ。\n");
printf("%sでっせ。\n");
はすべて間違いです。
printf("%sです。\n", s);
printf("%sだよ。\n", s);
printf("%sでっせ。\n", s);
No.2
- 回答日時:
→文字列パターン1の場合、関数1を呼び出す。
→文字列パターン2の場合、関数2を呼び出す。
→文字列パターン3の場合、関数3を呼び出す。・・・・・・
呼び出す関数群の引数の並びが同じであるならば、
関数ポインターを使って
#include <stdio.h>
#include <string.h>
typedef void (*func)(char *s);
void f0(char *s)
{
printf("%sです。\n");
}
void f1(char *s)
{
printf("%sだよ。\n");
}
void f2(char *s)
{
printf("%sでっせ。\n");
}
void f3(void)
{
printf("どれでもないよ。\n");
}
int main(void)
{
char *s[] = { "abc", "def", "ghi" }, p[4];
func f[] = { f0, f1, f2 };
int i;
while (1) {
printf("3文字の文字列を入力(zzzで終了) > ");
scanf("%3s", p);
if (strcmp(p, "zzz") == 0) {
break;
}
for (i = 0; i < sizeof(s)/ sizeof(s[0]); i++) {
if (strcmp(p, s[i]) == 0) {
(*f[i])(p);
break;
}
}
if (i == sizeof(s)/ sizeof(s[0])) {
f3();
}
}
return 0;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Indirect関数について、Formulatextで抽出した数式を参照したい。 1 2022/12/15 11:16
- C言語・C++・C# C言語の質問です。 以下の命令を実行するプログラムを作りました ①文字列aとbの長さを表示 ②aとb 1 2022/04/29 15:35
- その他(データベース) Accessのクエリで1フィールドの抽出条件設定をNullでなく全角半角含む空白のみの文字列でない文 1 2023/04/24 15:20
- C言語・C++・C# いまc言語の標準ライブラリ文字列を勉強しているのですがいまいちわかりません。 strcmpとmemc 5 2023/07/04 15:34
- Excel(エクセル) エクセルで2つの表を比較して、文字列が同じだが、その行のある値が違うものを抽出したい 1 2022/10/06 21:48
- その他(プログラミング・Web制作) awkの文字列比較はPOSIXロケールまたはCロケールにおいてバイナリ値の比較に使えるか gawkな 1 2023/04/22 09:21
- Excel(エクセル) 【画像あり】A1が●+B1と同じ文字がB列にある+C1と同じ文字がC列にある場合D1に〇を付ける 3 2023/03/09 18:18
- Visual Basic(VBA) EXCEL VBAで教えてください。 1 2022/12/22 04:20
- Excel(エクセル) エクセル関数の変わった使い方 3 2022/05/13 17:12
- Excel(エクセル) Excelの空文字判定について 7 2023/01/06 13:25
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
矢印キーを押下してコンソール...
-
C言語で複数列のデータを1列の...
-
char型2つを結合し、short型に...
-
C言語で型汎用性のある関数を作...
-
ファイルを辞書順に並べ替える...
-
ファイルから数字列を16進数の...
-
reallocとstrtokの併用について
-
【C言語】全角文字の配列を、全...
-
Cプログラムについて
-
printf による16進表示について
-
#defineが使用するメモリ領域に...
-
Ç言語でファイルサイズを変更す...
-
C++で指定文字列のカウント方法...
-
処理系によって。
-
コマンドファイルから、ビット...
-
配列への文字列の格納について
-
構造体メンバの初期化
-
fread処理について
-
fgetsがうまくいきません。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
#defineが使用するメモリ領域に...
-
C言語のプログラムで、途中で止...
-
printf による16進表示について
-
空白を含んだ文字列がうまく格...
-
プログラミングの授業の課題です
-
【C言語】全角文字の配列を、全...
-
構造体メンバの初期化
-
Cでファイルの行数をカウントす...
-
char型2つを結合し、short型に...
-
矢印キーを押下してコンソール...
-
C言語で複数列のデータを1列の...
-
終了条件Ctrl+zについて,結果表...
-
Ç言語でファイルサイズを変更す...
-
エラーについて質問です。
-
C言語でのCSVファイルの読み出...
-
C++で指定文字列のカウント方法...
-
VC++でSQLへSELECT文を送ったの...
-
fscanfの使い方
-
c言語で文書を読み込み、単語の...
おすすめ情報