例から始めます
me@blabla ./example + 3 5
8 を返す必要があります。
引数は取りますが、「+」をから変換するにはどうすればよいですか
char* opp = argv[1];
に
+
コード内で使用するには?
かなりの数の演算子を使用したいので、大きな if ステートメントを使用せずにこれを行う方法はありますか?
私はそれが明確であることを願っています、ありがとう!
char
から演算子への何らかのマッピングが必要になります。すでにいくつかの整数変数3
とを持っていると仮定すると、簡単な解決策は次のステートメントを使用することです。5
x
y
switch
switch (opp[0]) {
case '+': result = x + y; break;
case '-': result = x - y; break;
// and so on...
}
std::map
または、 from char
s to を持つこともできますstd::function<int(const int&,const int&)>
:
typedef std::function<int(const int&,const int&)> ArithmeticOperator;
std::map<char, ArithmeticOperator> ops =
{{'+', std::plus<int>()},
{'-', std::minus<int>()},
// and so on...
};
int result = ops[opp[0]](x,y);
次のようなものはどうですか:
char op = argv[1][0];
if (op == '+')
add(argv[2], argv[3]);
またはおそらく:
switch (op)
{
case '+':
add(argv[2], argv[3]);
break;
...
}
受け入れる演算子のリストに対して、指定された演算子をテストできます。
#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
int main(int argc, char* argv[])
{
if (argc <= 3)
{
std::cout << "<op> <num1> <num2>\n";
return 1;
}
const std::string op = argv[1];
const int arg1 = boost::lexical_cast<int>(argv[2]);
const int arg2 = boost::lexical_cast<int>(argv[3]);
cout << arg1 << op << arg2 << " = ";
if (op == string("+")) // <== Here is where you turn "+" into +
{
cout << arg1 + arg2 << "\n";
}
else if (op == string("*")) // <== or "*" into *
{
cout << arg1 * arg2 << "\n";
}
else
{
cout << "I don't know how to do that yet.\n";
return 2;
}
return 0;
}
この問題の最も用途の広い解決策は、より大きな入力にスケーリングできるように解析ツリーを構築することです。
解析ツリーは基本的に、オペランドと演算子の間の関係を表すバイナリ ツリーです。リーフまでの各ノードは演算子であり、リーフ自体はオペランドであるため、式を分析または解釈する場合は、一番下から開始できます。ツリーを上っていき、式を解決していきます。
これを行う最も簡単な方法は、再帰降下パーサーを作成することです。1 つは演算子用、もう 1 つはオペランド用の 2 つのスタックを作成します。演算子を見つけたら、それらをそれぞれのオペランドと共にスタックにプッシュし、演算子に到達すると、優先順位が低い場合は、必要に応じてスタックとオペランドから 1 つの演算子をポップし、ノードを作成します。
独自のパーサーを作成する手間をかけたくない場合は、boost にそれを行うためのユーティリティがいくつかあることがわかりました。しかし、私はそれらを個人的に使用していないので、ドキュメントを調べて、それらが役立つかどうかを確認する必要があります. http://www.boost.org/doc/libs/1_34_1/libs/spirit/doc/trees.html