C ++字符串流ignore()不起作用

时间:2017-09-29 02:02:43

标签: c++ stringstream

我正在解决有关hackerrank的问题,并遇到了涉及字符串流的问题。

https://www.hackerrank.com/challenges/c-tutorial-stringstream/problem

对于提取数据,hackerrank举了一个例子:

stringstream ss("23,4,56");
char ch;
int a, b, c;
ss >> a >> ch >> b >> ch >> c;  // a = 23, b = 4, c = 56

然而,当我尝试将其导出到矢量时,我必须逃避','使用:

stringstream ss(str);
vector<int> vect;
int i;

while (ss >> i)
{
vect.push_back(i);

if (ss.peek() == ',')
    ss.ignore();
}

为什么我不能使用提取操作来获取所需的单词?该流不应该逃脱&#39;(对不起noob级别的问题)?

2 个答案:

答案 0 :(得分:3)

operator>>提取下一个分隔标记,只要字符实际属于请求的数据类型。因此,当使用operator>>来阅读int时,它只会提取数字,而不是字母,标点符号等。这意味着必须单独读取数字后面的逗号。

在第一个例子中:

  1. ss >> a读取流中的第一个int
  2. 然后>> ch读取后面的逗号
  3. 然后>> b读取下一个int
  4. 然后>> ch读取后面的逗号
  5. 然后>> c读取下一个int
  6. 在第二个例子中:

    1. ss >> i读取流中的下一个int,如果失败或EOF打破循环
    2. 然后ss.peek()检查是否存在逗号(因为上一个int没有逗号),如果找到则ss.ignore()跳过它
    3. 转到#1
    4. 如果您尝试使用operator>>来读取不存在的逗号,则会设置流的eofbit状态并导致提取失败。如果您使用while (ss >> i >> ch),则while会在达到最后false时评估为int。即使ss >> i成功,>> ch也会失败,因此i将不会添加到vector

      理论上,您可以使用if (ss.peek() == ',') ss.ignore();替换循环内的char ch; ss >> ch。最终效果是相同的,至少对于像"23,4,56"这样的字符串。但是,让我们说你给了"23 4 56"这样的东西。第一个示例无法正确处理,但第二个示例在使用peek()+ignore()时处理得很好,但在使用ss >> ch时却没有。

答案 1 :(得分:1)

我认为您可以使用此代码来逃避&#39;,&#39;

std::string valstr;
while (std::getline(ss, valstr, ','))
{
    vect.push_back(std::stoi(valstr));
}