2

如果我有一行输入字符串,std::cin其中包含由空格分隔的字符串和整数。将它们分开和储存的最有效方法是什么?

例如:

input: "Move 1 to 2" 
variables for storing: 
string a, b; 
int orig, dest;

编辑:

我已按照建议应用了以下代码。但是,当我输入“将 9 移到 1”时,似乎只有“移动”一词正确存储在向量 strs 中。

    string command;
    cin >> command;
    vector<int> ints;
    vector<string> strs;

    string strval;
    int intval;
    stringstream test;
    test.str(command);
    while(true) {
        if(test.eof())
            break;

        if(test >> strval) {
            strs.push_back(strval);
        }
        else if(test >> intval) {
            ints.push_back(intval);
        }
        else {
            cout << "error!" << endl;
        }
    }

解决问题:
使用

getline(cin, command);

代替

cin >> command;
4

2 回答 2

2

我将假设整数和字符串的顺序是未知的。您可以利用cinto bool 的转换来确定您是否检测到 int。

基本上,(cin >> intValue)(where intValueis an int) 是一个表达式,true如果接下来的几个字符构成可以放入 an 的有效数字,则返回intfalse否则返回。同样的原则也适用于其他类型,例如string. 这些可以在 if 语句中使用,例如

int intValue;
if (cin >> intValue) {  //evaluates to true or false
// do something
} else {
// do something else
}

您可以将其与 while 循环一起使用来解析整个输入,如下所示:

vector<int> ints; //container to store ints
vector<string> strings; //container to store ints

while(true) {

  int intValue;
  string stringValue;
  if(cin.eof())  //exit the loop when the end of the input is reached
    break;

  if(cin >> intValue) {  //if this is true, then an int was successfully read into intValue
    ints.push_back(intValue);
  } else if (cin >> stringValue) { //if this is true, int could not be read but string was successfully read
    strings.push_back(stringValue);
  } else {
    cout << "Error: unknown value read in, not recognized as int or string" << endl;
    exit(-1);
  }
}

编辑:

我刚刚读到您已经将该行作为字符串。上述相同的解决方案将起作用,只需使用 stringstream 而不是 cin:

string line; //the line that you already have, initialized elsewhere

stringstream ss(line.str()); //convert the line to a stringstream, treat it similar to cin
vector<int> ints;  //container to store ints
vector<string> strings;  //container to store strings

while(true) {

  int intValue;
  string stringValue;
  if(ss.eof())
    break;

  if(ss >> intValue) {
    ints.push_back(intValue);
  } else if (ss >> stringValue) {
    strings.push_back(stringValue);
  } else {
    cout << "Error: unknown value read in, not recognized as int or string" << endl;
    exit(-1);
  }
}

在您的示例中,即 line Move 1 to 2,向量将包含1and 2,并且向量将包含Moveand to

于 2013-08-05T00:10:24.713 回答
1

您正在寻找解析文本。

您的“输入语法”......未指定,但这里有一个解析器框架,例如 Boost Spirit:

#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/qi.hpp>

namespace qi    = boost::spirit::qi;

struct Command { std::string name; int a, b; };

BOOST_FUSION_ADAPT_STRUCT(Command, (std::string, name)(int,a)(int,b))

int main()
{
    const std::string input("Move 2 to 4");

    auto f(begin(input)), l(end(input));

    Command parsed; 

    bool ok = qi::phrase_parse(f,l,
           qi::string("Move")     >> qi::int_ >> "to"   >> qi::int_
         | qi::string("Multiply") >> qi::int_ >> "by"   >> qi::int_
         | qi::string("Subtract") >> qi::int_ >> "from" >> qi::int_
         , qi::space, parsed);

    if (ok)   
    {
        std::cout << "parse success\n";
        std::cout << "parsed: '" << parsed.name << "' with (" << parsed.a << ", " << parsed.b << ")" << "\n";
    }
    else std::cerr << "parse failed: '" << std::string(f,l) << "'\n";

    if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";
}

印刷

parse success
parsed: 'Move' with (2, 4)
于 2013-08-05T00:31:27.070 回答