【问题标题】:Ignoring whitespace in string stream doesn't work with skipws flag忽略字符串流中的空格不适用于 skipws 标志
【发布时间】:2020-01-18 14:32:51
【问题描述】:

我正在尝试解决一个问题,该问题评估像 10+20 这样的字符串中的简单表达式应该返回 30

问题是字符串可以包含空格,所以我使用stringstringskipws 标志它适用于字符串中的空格,如10 + 20 等,但是当空格最后它没有正确传递.

这就是我解析字符串的方式

void build_stack(const string& str) {
    istringstream ss(str);

    char op;
    int op1, op2;
    ss>>skipws>>op1;
    operands.push(op1);
    while(!ss.eof()) {
        ss>>op;
        operators.push(op);
        ss>>op2;
        operands.push(op2);
    }
}

带有各种字符串输入的完整代码here in rextester

当字符串为 3+5 / 2 时,我的堆栈构建为 operands => 2 2 5 3 operators => / / +

当字符串为3+5 / 2(即带有尾随空格)时,我的堆栈构建为 operands => 2 5 3 operators => / +

我试过了

while(ss.peek() == ' ') {
    char c; ss>>c;
}

但这是在看到空格后删除所有字符。

【问题讨论】:

标签: c++ string stringstream


【解决方案1】:

例如"3+5 / 2 ":

  1. ss>>skipws>>op1;

    3 写入op1

  2. operands.push(op1);

    op1 被推入operands

  3. while(!ss.eof()) {

    是真的

  4. ss>>op;

    + 被写入op

  5. operators.push(op);

    op 被推入operators

  6. ss>>op2;

    5 被写入op2

  7. operands.push(op2);

    op2 被推入operands

  8. while(!ss.eof()) {

    是真的

  9. ss>>op;

    / 写入op

  10. operators.push(op);

    op 被推入operators

  11. ss>>op2;

    2 写入op2

  12. operands.push(op2);

    op2 被推入operandsss 包含一个空格,不是空的

  13. while(!ss.eof()) {

    是真的

  14. ss>>op;

    无法读取,/ 停留在op,eof 已设置

  15. operators.push(op);

    op 被推入operators

  16. ss>>op2;

    无法读取,2 停留在op2

  17. operands.push(op2);

    op2 被推入operands

  18. while(!ss.eof()) {

    是假的

对比示例"3+5 / 2"

  1. ss>>skipws>>op1;

    3 写入op1

  2. operands.push(op1);

    op1 被推入operands

  3. while(!ss.eof()) {

    是真的

  4. ss>>op;

    + 写入op

  5. operators.push(op);

    op 被推入operators

  6. ss>>op2;

    5 写入op2

  7. operands.push(op2);

    op2 被推入operands

  8. while(!ss.eof()) {

    是真的

  9. ss>>op;

    / 写入op

  10. operators.push(op);

    op 被推入operators

  11. ss>>op2;

    2 写入op2

  12. operands.push(op2);

    op2 被推入operandsss 为空,eof 已设置

  13. while(!ss.eof()) {

    是假的

你可以修复它

void build_stack(const string& str) {
    istringstream ss(str);

    char op;
    int op1, op2;
    ss>>skipws>>op1;
    operands.push(op1);
    while(true) {
        if (!(ss>>op)) break;
        operators.push(op);
        if (!(ss>>op2)) break;
        operands.push(op2);
    }
}

【讨论】:

  • 感谢@ThomasSablik 的逐步解释。因此,通过修改堆栈中的值来确认堆栈中的值被重用,并看到虚拟值被插入新源location。我的问题仍然是因为设置了忽略空白标志,所以不应该ss.eof() 立即检查剩余流是否有效或最后一次读取调整空白字符?现在我改用while(ss>>op)。避免两次休息。
  • 首先,ss>>skipws 在您的示例中不执行任何操作。 skipws 是默认行为:en.cppreference.com/w/cpp/io/manip/skipws。在输入之前跳过空格,而不是在输入之后。 "启用或禁用 前导 空格的跳过" 如果没有两个中断输入,如 5+5+ 将产生 5 5 5+ +
猜你喜欢
  • 2018-08-30
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-19
相关资源
最近更新 更多