在getline()之后获取字符串

get string after getline()

本文关键字:获取 字符串 之后 getline      更新时间:2023-10-16

我想保持一个带空格的字符串,因此我使用了 getline(),但是如果有 -e,则我想获得另一个字符串(无空格(,例如 s2中的字符串,但是由于在我的代码中,我在使用getline()时会失去破折号,因此我似乎无法实现自己的尝试。任何建议都会有所帮助。

//example input: -f name -b blah blah -e email
//looking for output:
//name 
//blah blah
//email

string s,s1,s2;
char check_character;
while (cin.peek() != 'n')
{
    if (cin.get() == '-')
    {
        check_character = cin.get();
        switch(check_character)
        {
            case 'f':
            cin >> s;
            break;
            case 'b':
            if(cin.peek() != 'n')
                getline(cin, s1, '-');
            else if(cin.peek() =='n')
                getline(cin, s1);
            break;
            case 'e':
            cin>> s2;
            break;
        }
    }
}
cout << s << endl << s1 << endl << s2 << endl;
return 0; 

}

一个更好的选择是对getline()进行一次调用,然后解析"命令"字符串。从" - "或find('-')

上的简单split()来实现这一目标有很多选择。

getline()从IS中提取字符并将其存储到str中,直到找到划界字符DELIM或NEWLINE字符'n'

如果找到了定界符,则提取并丢弃它(即未存储,下一个输入操作将在其之后开始(。

我将在这里做几个假设:

  1. 即使在" -b"之后,您也永远不会期望' n'(即使在输入字符串的末尾((您的代码当前将读取(
  2. 您希望仅接受每种参数中的1个(因为您的当前代码会踩踏任何以前的条目(

regex_search将使用regex很好地处理此操作:

(?:s*-fs+(w+)|s*-bs+([^-]+)|s*-es+(w+))*

实时示例

您需要首先从cin读取变量,例如string input。这可以像:

一样完成
getline(cin, input)

一旦您获得输入,就可以简单地做:

if(smatch m; regex_search(input, m, regex{ "(?:\s*-f\s+(\w+)|\s*-b\s+([^-]+)|\s*-e\s+(\w+))*" })) {
    if(m[1].length() > 0U) {
        cout << "-f " << m[1] << endl;
    }
    if(m[2].length() > 0U) {
        cout << "-b " << m[2] << endl;
    }
    if(m[3].length() > 0U) {
        cout << "-e " << m[3] << endl;
    }
}

实时示例

如果您采用整行阅读的方法,并且不想使用boost程序选项或getopts,则可以自己解析该行(如建议(。这将是一种方法,作为您代码中即时解析的替代方法:

#include <iostream>
#include <string>
#include <tuple>
#include <vector>
using std::cout;
using std::endl;
using std::get;
using std::literals::string_literals::operator""s;
using std::make_tuple;
using std::string;
using std::tuple;
using std::vector;
static auto chunkLine(string const& line)
{
  auto result = vector<string>{};
  auto i = string::size_type{};
  while (i != string::npos && i < line.size())
  {
    auto pos = line.find(" -", i);
    auto count = pos == string::npos ? pos : (pos - i);
    result.push_back(line.substr(i, count));
    i = pos + (pos != string::npos ? 1 : 0);
  }
  return result;
}
static auto parseChunks(vector<string> const& chunks)
{
  auto result = vector<tuple<string, string>>{};
  for (auto const& chunk : chunks)
  {
    auto pos = chunk.find(" ");
    if (pos != string::npos && chunk[0] == '-')
    {
      auto kv = make_tuple(chunk.substr(1, pos-1), chunk.substr(pos+1));
      result.push_back(kv);
    }
  }
  return result;
}
int main()
{
  auto line = "-f name -b blah blah -e email"s;
  auto keyValueTuples = parseChunks(chunkLine(line));
  for (auto const& kv : keyValueTuples)
  {
    cout << get<1>(kv) << endl;
  }
}

您解析的方式肯定可以得到改善,但是这个答案与之无关。我认为您要寻找的是简单地将-炭删除后,将CC_14 Char放回流中。在这种情况下,您可以只使用.putback()方法

if (std::cin.peek() != 'n')
{
    std::getline(std::cin, s1, '-');
    std::cin.putback('-');
}

我认为您应该在代码中键入getline之前放置cin.ignore:

`string s,s1,s2;
char check_character;
while (cin.peek() != 'n')
 {
    if (cin.get() == '-')
 {
    check_character = cin.get();
    switch(check_character)
    {
        case 'f':
        cin >> s;
        break;
        case 'b':
        if(cin.peek() != 'n')
            cin.ignore
            getline(cin, s1, '-');
        else if(cin.peek() =='n')
            cin.ignore
            getline(cin, s1);
        break;
        case 'e':
        cin>> s2;
        break;
    }
}
}
cout << s << endl << s1 << endl << s2 << endl;
return 0; `