如何解析具有简单语法的输入命令?

时间:2018-02-09 02:43:44

标签: c++ parsing

我正在开发一个程序,该程序应该接受用户的指令并用它做一些事情。它使用类和对象来知道要做什么。但是,某些命令只需要用户输入2个内容,其他命令需要3,4个等。例如:

request> balance 2

此调用是检索客户2的余额。但是这个电话:

request> deposit 2 30

这应该是30美元存入客户2的帐户。

如何让程序理解用户可以输入由空格分隔的2个变量,还是更多?

我认为可能将整个用户输入作为字符串然后解析可能更容易......

char temp[257];
scanf("%s", temp);

但是,如果您调试并输出这个所谓的字符串,它只输出用户输入的最后一项..所以如果用户输入

request> balance 3

它只抓住3并将其存储到临时......

我认为你们得到的图片,我需要能够为终端提供多个字符串,整数等,并将每个单独的一个存储到自己的变量中。任何帮助将不胜感激!

一些虚拟代码供参考:

#include <iostream>
#include <stdio.h>
#include <cstdlib.h>

including namespace std;

int main()
{
    char temp[257];
    int x, y, z;

    printf("request: ");
    scanf("%s", temp);     // I need this to be able to scan more than one 
                           // thing, and know where to store them
    scanf("%s %d %d", temp, x, y);
    // because if I do this ^^, then it will just hang if I only need x and 
    // not y.

    // Do some random stuff w/ variables now

    return 0;

}

2 个答案:

答案 0 :(得分:1)

您的示例代码看起来很像C,除了using namespace std;,您也不应该这样做,但这是另一个主题。以下是使用C ++构造处理用户输入(一次性行)的快速而肮脏的方法。

#include <iostream>
#include <sstream>

int main()
{
    std::string line;              ///< hold user input as string
    std::getline(std::cin, line);  ///< get the whole line at once
    std::stringstream ss(line);    ///< stream for processing line arguments

    /*std::string args;
    while (ss >> args)
    {
        // decide what to do with each input argument here
        std::cout << "args= "<< args << std::endl;
    }*/
    // if you "know" your input arguments you don't need a loop
    std::string command;
    int val1(-1);
    int val2(-1);
    ss >> command >> val1 >> val2;

    std::cout << "command = " << command << " val1="
    << val1 << " val2=" << val2 << std::endl;

    return 0;
}

答案 1 :(得分:1)

虽然你有一个可靠的答案,但是你是否想要开始使用C ++或C解决方案仍然有点含糊不清。为了完整起见,您可以使用fgets(您的信息流为stdin),然后使用{{1}来调用sscanf来解析用户输入的不同数量的项目返回处理不同的情况。

允许1输入显示余额和2输入以更新平衡的简短示例可以如下进行。程序退出第一个匹配失败(因此您只需键入switch即可退出)。 输入失败将被忽略。

'q'

注意: #include <stdio.h> enum { NMMAX = 16, BUFSZ = 256 }; /* if you need constants, define them */ typedef struct { /* simple struct for user name and balance (integer) */ char name[NMMAX]; long balance; } account_t; int main (void) { account_t accounts[] = {{"John", 12305}, {"Paul", 388541}, {"George", -38112}, {"Ringo", 1}}; int naccts = sizeof accounts / sizeof *accounts; for (;;) { /* loop continually until matching failure or user cancels */ char buf[BUFSZ] = ""; int acct = 0, rtn = 0; double bal = 0; fputs ("request> ", stdout); /* display prompt */ if (!fgets (buf, BUFSZ, stdin)) { /* read input, check EOF */ fprintf (stderr, "error: user canceled input (ctrl+d)\n"); return 1; } /* separate inputs into acct and bal, rtn holds number of inputs */ rtn = sscanf (buf, " %d %lf", &acct, &bal); if (rtn && acct > naccts) { /* check if requested account valid */ fprintf (stderr, "error: invalid account.\n"); continue; } switch (rtn) { /* switch on sscanf return */ case 0 : /* use matching falure to exit */ goto finished; break; case 2 : /* 2 inputs - update balance */ accounts[acct].balance += (long)(bal * 100); case 1 : /* 1 input - show balance */ printf ("%-15s : $%.2f\n", accounts[acct].name, accounts[acct].balance / 100.0); break; } } finished:; return 0; } 堕落是有意的。)

示例使用/输出

case 2 :

祝你最终写出来的语言好运。