2013-02-01 28 views
1

我会用一个例子开始命令行以操作和使用它们的代码中操作

[email protected] ./example + 3 5 

应该返回8.

我接受的参数中,但我怎么转换“+” 从

char* opp = argv[1]; 

+ 

在我的代码里面使用?

因为我想使用相当多的操作符有没有办法做到这一点,而不使用大的if语句?

我希望那样清楚,谢谢!

+0

你想要的是解析一个数学表达式 - 抱歉,但这不会是微不足道的。 – 2013-02-01 22:34:19

回答

1

您可以根据您接受的操作符列表测试给定的操作符。

#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; 
} 
+0

但我想用很多运营商即。 *, - ,/,%等。并没有一个大的if或switch语句? – user1724416

+0

@ user1724416你迟早会得到某种条件陈述。您不能在语言中使用输入作为运算符。 –

2

如何像:

char op = argv[1][0]; 

if (op == '+') 
    add(argv[2], argv[3]); 

或者可能:

switch (op) 
{ 
case '+': 
    add(argv[2], argv[3]); 
    break; 
... 
} 
5

你必须有一些来自char到操作类的映射。假设你已经有了一些整型变量35xy,简单的解决方法是使用一个switch声明:

switch (opp[0]) { 
    case '+': result = x + y; break; 
    case '-': result = x - y; break; 
    // and so on... 
} 

或者,你可以有一个std::mapchar s到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); 
+1

+1地图解决方案! – us2012

0

这个问题的最通用的解决方案是构建一个分析树,以便您可以将其扩展为更大的输入。

解析树基本上是二叉树,它提供了操作数和运算符之间关系的表示,每个叶节点都是运算符,叶子本身就是操作数,所以当你想分析或解释一个表达式时,你可以从树的底部开始,并在树上时解析表达式。

最简单的方法是通过制作递归下降解析器,您创建两个堆栈,一个用于运算符,另一个用于操作数,当您找到运算符时,将它们与它们各自的操作数一起推入堆栈,以及何时您以较低的优先级访问操作员,并根据需要从堆栈和操作数中弹出一个操作员,然后创建一个节点。

如果你不想经历创建自己的解析器的麻烦,我发现boost有一些实用程序可以帮助你。但我没有亲自使用它们,所以你必须仔细阅读文档以查看它们是否有用。 http://www.boost.org/doc/libs/1_34_1/libs/spirit/doc/trees.html