
C言語にて開発を行っています。
今回、テキストファイルに記述された関数名および引数を読み取り、プログラム側でこれを実行する処理を実装しようと考えています。
その際、テキストから読み込んだ文字列によって処理を振り分けることを省略したいと思っていますが方法が分からず困っています。
以下が読み取る対象のテキストファイルの例です。
@function_A;arg1;arg2
@function_B;arg1;arg2
・・・
このとき、テキストファイルから読み取った文字列に応じた関数を実行する、というところまでは実装できています。
(読み取った文字列がfunction_Aであれば、同名の関数を実行します)
現在の実装は、以下のようなイメージです。
command = "読み取った文字列(@function_Aなど)";
if(command == "@function_A"){ function_A(arg1, arg2);}
else if(command == "@function_B"){ function_B(arg1, arg2);}
・・・
しかし、この実装では関数が増えるに従って
if(command == "function_X"){...}をどんどん追記していく必要があります。
今後関数の数が膨大になっていく予定なので、これを追記せずに読み込んだ文字列と同名の関数を実行できるようにしたいと思っています。
以下の様なイメージです。
function_A.cというファイルに関数function_A(arg1, arg2)を実装します。
同様にして、 function_B.cに関数function_B(arg1, arg2)を実装します。
main()内にて、
char command[] = "読み取った文字列(function_Aなど)";
command(arg1, arg2);
とすることによって、function_A()関数を実行できるようにすることが目的です。
もちろん、この場合のcommandはchar型ですから、上記のような記法が不可能なことは分かっていますが、似たようなことを実装したいと思っています。
どのようにすれば実装できるのでしょうか。
今後、関数の数だけfunction_A.cのようなファイルが増え、最終的に200近くになる予定ですし、
if(command == "@function_A"){ function_A(arg1, arg2);}
else if(command == "@function_B"){ function_B(arg1, arg2);}
・・・
の記述忘れによる動作不良を防ぐためにもこれを実装したいと思います。
A 回答 (7件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
Cの規格上は既に回答に出てる通りの方法しかないです。
プラットホームに依存してよければ、
WindowsだとGetProcAddress, linuxや一部unix系だとdlsymを使う手もあります。
No.5
- 回答日時:
ANo.1です。
ハッシュテーブルへの登録は関数の数だけ書く必要があります。
set_table(table, "@function_A", function_A);
set_table(table, "@function_B", function_B);
...
のような感じですね。
これも省略したければCソースを自動生成するスクリプトなど作るしかないでしょう。
実際に文字列から関数を取得する部分はハッシュテーブルを使うならif羅列とは全然違います。
ハッシュテーブルは文字列からハッシュ値を計算して、このハッシュ値の位置に文字列と値(関数ポインタ)を格納します。検索する際もハッシュ値を計算してハッシュ値の位置の文字列が探しているものか確認して値を取り出します。
従って、検索時は(ほとんどの場合)文字列の比較は一回だけで済みます。
エントリが200もあるなら実行時の速度も全然早くなるのでハッシュテーブルを使うべきでしょう。

No.4
- 回答日時:
> @function_A;arg1;arg2
> @function_B;arg1;arg2
から、
funciton_A(arg1, arg2);
function_B(arg1, arg2);
という、Cのソースを生成して、それを、コンパイル、リンクして実行する。
というのは?
No.3
- 回答日時:
念の為に確認しますが
> command = "読み取った文字列(@function_Aなど)";
> if(command == "@function_A"){ function_A(arg1, arg2);}
本当に = で代入、 == で比較、とかはやってないですね?
struct FunctionTable{
char name[STRMAX] ;
void (*func)();
} table[] = {
{ "@function_A", function_A },
{ "@function_B", function_B }
} ;
のように、文字列と関数へのポインタののテーブルを作って
for(i=0; ...
...
if( strcmp( command, tablle[i].name ) == 0 ) {
table[i].func(arg1,arg2);
}
みたいに、文字列比較→該当する関数を実行 というのが定番でしょう。
他の言語、特にスクリプト言語には
command="function_A(arg1.arg2)" ;
eval( command ) ;
みたいに書いて、文字列をそのまま命令として実行できるものがあります。
しかし、C言語にはこのような仕組みは無いので、地道な方法しかありません。
記述漏れを防ぐには、自動化すればよいでしょう。
C言語のソースから、テーブルを自動で作るようなプログラムを準備し,本体をコンパイルする前に実行します。
cretateTable funcitons.c → functions.cを解析して、table.c が作成される
というような感じで。
他に、共有ライブラリを使う方法があります。
f = 共有ライブラリからシンボルを探す関数( commad ) ;
f(arg1,arg2) ;
という感じです。
WindowsならDLLにfunction_A..等の実体→ LoadLibrary→GetProcAddress でしょうか。
No.1
- 回答日時:
ハッシュテーブルか何かを使って文字列と関数ポインタの対応表を実装する。
プログラムの起動時に文字列と関数ポインタの対応を上記対応表に登録する処理を入れる。
実行時は文字列で対応表を引いて関数ポインタを得て実行する。
関数は全て同じプロトタイプになるようにしておく必要があります。
C++だと対応表はhash_mapとかのライブラリクラスを使って良いですがCだと自前で実装ですかね。
あと対応表への登録は明示的に実行するしかないですね。
この回答への補足
文字列と関数ポインタの対応表を作成するということは、結局のところやっていることは
if(command == "@function_A"){ function_A(arg1, arg2);}
else if(command == "@function_B"){ function_B(arg1, arg2);}
に相当するものを関数の追加に応じて記述していくことになると思うのですが、この認識は合っていますでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数でy=g(x)のgとは何の略です...
-
functionから別のfunctionを実...
-
Matlabで自作関数をオーバーロード
-
クリックすると上に開くアコー...
-
JAVAスクリプトで指定時間以降...
-
クロージャーの利点が理解できない
-
idを使わずにonclickで自身の要...
-
jQuery タグで囲まれたテキスト...
-
無名関数を使うメリットは何で...
-
同じIDで定義した要素の配列を...
-
GASでundefinedエラーが出ます
-
C#OpenCv V4にのエラーに関する...
-
javascriptで複数キーワード検...
-
onclickとonkeypressの重複
-
コールバック関数(?)をループし...
-
cgiでポーリングして取得したデ...
-
onchangeイベントを使ってspan...
-
class指定したHTML要素の背景色...
-
別のSubで宣言されている変数を...
-
static constメンバ変数(配列)...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
functionから別のfunctionを実...
-
idを使わずにonclickで自身の要...
-
関数でy=g(x)のgとは何の略です...
-
クリックすると上に開くアコー...
-
Matlabで自作関数をオーバーロード
-
XMLHttpRequestでキャッシュを...
-
javascriptのenchantの打ちミス
-
ASP 最終日の表示
-
javascriptのレキシカルスコー...
-
jQueryでのレスポンシブが綺麗...
-
jQueryを利用したアコーディオ...
-
イベントハンドラの関数の引数...
-
getElementByIdを使用したグロ...
-
関数名をテキストから読み込む...
-
delphi6を使っています。
-
JavaScript 宣言 について
-
Ajaxでデータベース(PostgreSQL)
-
functionはhtmlやjsに2度使えま...
-
Javascriptの丸括弧の意味
-
JavaScript/jQuery で元画像フ...
おすすめ情報