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で質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- Visual Basic(VBA) VBA 改行コードの取り方 1 2022/03/22 14:14
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
- JavaScript ソースコードのいじる場所が分かりません。 1 2022/12/23 02:06
- Visual Basic(VBA) パーソナルXLSBのfuctionを呼び出すと「Functionが定義されていません」のエラーになる 2 2022/08/22 22:51
- Visual Basic(VBA) EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい 1 2023/03/16 07:05
- Visual Basic(VBA) 数字が「0」の列を削除するため、下記のコードを実行しましたが、コンパイルエラーSubまたはFunct 3 2022/12/04 00:00
- Excel(エクセル) 【Excel】複数列ごとに取得するセルを変更したい 2 2023/03/23 21:04
- Excel(エクセル) VBA オリジナル関数で選択セルの合計を作成したい 3 2023/03/19 19:45
- Visual Basic(VBA) VBAでfunctionを利用しようとしたときに「引数は省略できません」というエラーが出ます 1 2022/10/15 16:30
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
functionから別のfunctionを実...
-
関数でy=g(x)のgとは何の略です...
-
Javascriptで引数の参照渡しか...
-
CDの曲をケータイのSDに移す
-
ASP 最終日の表示
-
JavaScript 、function、return
-
jQueryでzipを解凍読み込みする...
-
小数点以下を5刻みで表示
-
jQuery cssメソッドでの変数の...
-
現在地の取得について
-
Javascriptで文字列操作
-
jQueryを使用したギャラリー
-
idを使わずにonclickで自身の要...
-
jQueryの"return false"の役割...
-
javascriptで自動計算フォーム...
-
日本語入力の禁止
-
URLの一部をコピーできるブック...
-
google apps scriptの終了のさせ方
-
空の配列に2次元配列の追加
-
第3日曜日のみの日付を取得、...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
idを使わずにonclickで自身の要...
-
functionから別のfunctionを実...
-
関数でy=g(x)のgとは何の略です...
-
jslintのエラーについて質問
-
クリックすると上に開くアコー...
-
XMLHttpRequestでキャッシュを...
-
ajax反映後のjqueryが動かない
-
function(e)の意味を教えてくだ...
-
要素名がスペースを含む場合のj...
-
jQueryの :not() .not() が有効...
-
jQueryでzipを解凍読み込みする...
-
関数名をテキストから読み込む...
-
getElementByIdを使用したグロ...
-
jqueryuiのdialog
-
jqueryのグローバル変数とロー...
-
jQuery 同じ処理を関数にまとめ...
-
XMLHttpRequestオブジェクトが...
-
addEventListener()でリスナー...
-
drawImageの描画順序の指定につ...
-
javascript(jQuery)でセル内...
おすすめ情報