使用stringstream.fail()检查输入是int还是string

时间:2013-10-04 15:29:26

标签: c++ string input int stringstream

我正在创建一个简单的函数printNode,它接受一个int或字符串“all”,并打印一个相应的输出。该函数的int方面效果很好,但是当我调用

printNode all

该函数打印“错误:无效参数”,我似乎无法弄清楚原因。

int main() {
    ...
    getline(cin, line)
    stringstream lineStream(line);
    stringstream elineStream(line);
    printNode(lineStream, elineStream);
    ...
}


int printNode(stringstream& lineStream, stringstream& elineStream) {
//String aspect of printNode
int nodeid;
string name;

// Parsing nodeid or name
lineStream >> nodeid;

// If parsing to nodeid fails, check if input is string "all"
if (lineStream.fail()) {
    elineStream >> name;
    if (elineStream.fail()) {
        if (elineStream.eof()) {
            cout << "Error: too few arguments" << endl;
            return 0;
        }
        else {
            cout << "Error: invalid argument" << endl;
            return 0;
        }
    }
    if (name != "all") {
        cout << "Error: invalid argument" << endl;
        return 0;
    }
    // Check for too many arguments
    elineStream >> ws; 
    if (!elineStream.eof()) {
        cout << "Error: too many arguments" << endl; 
        return 0;
    }

    // Print output for input "all" 
    cout << "Print: all nodes" << endl;
    return 1;
}

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

您将printNode all作为输入,而它只需要all。我尝试了你的代码并且它正常工作(当然,给它printNode all失败并且无效参数)。

作为旁注,您可以通过清除第一个字符串上的错误标志来避免使用两个流。也就是说,如果您在看到它读取数字失败后添加elineStream,那么lineStream可能只是lineStream.clear();


从你的措辞中,我看到一些奇怪的东西,我也想澄清(以防万一):

  

但是当我打电话时

printNode all

通过在命令行中写入,您不会调用函数。写入时会调用该函数:

printNode(lineStream, elineStream);

在你的源代码中。如果在命令行中编写printNode all,则所有字符串(因为您读取整行)都将传输到流,而不仅仅是all

答案 1 :(得分:0)

使用std::copy std::istream_iteratorstd::back_inserter将所有字​​词复制到std::vector,可以更轻松地获取“命令”及其所有选项。然后,它只是简单地检查向量的大小,看看命令是否合法。

这就行了:

std::vector<std::string> command_and_args;

std::copy(std::istream_iterator<std::string>(lineStream),
          std::istream_iterator<std::string>(),
          std::back_inserter(command_and_args));

if (command_and_args.size() == 0)
    std::cout << "Error: No command or arguments\n";
else if (command_and_args.size() == 1)
    std::cout << "Error: To few arguments\n";
else if (command_and_args.size() > 2)
    std::cout << "Error: To many arguments\n";
else
{
    // Got the command and one argument
    // Command in `command_and_args[0]`
    // Argument in `command_and_args[1]`
}

std::copy部分可用于所有命令,而检查必须是个人的。


编辑:实际上,如果您创建一个详细说明命令的结构(命令字符串,布尔值来判断是否需要参数,最小参数数量,最大参数数,以及命令处理程序的std::function对象。使用这种结构制作一个表,并通过它查找命令,检查参数计数(如果需要)然后调用函数对象。然后函数对象可以检查各个参数。