You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何StringStream使用noskipws提取字符后,后续字符串提取异常?

问题分析:stringstream提取字符后后续字符串提取失效的原因

预期输出Thisisatest.,但实际仅输出Thi。程序先通过noskipws从stringstream中提取前3个字符,后续尝试提取剩余字符串却失效,移除noskipws后问题解决,具体原因如下:

原代码

#include <sstream>
#include <iostream>
using namespace std;

int main() {
  string test = "This is just a test.";
  stringstream ss(test);
  
  char c;
  int i = 0;
  while (ss >> noskipws >> c) { 
    int ascii = (int)c;
    if (i > 2) { // break after writing 2 characters
      break;
    }
    i++;
    cout << c; 
  }

  // continue using the same sstring, 
  // but with a string instead of a char
  // notice that there is no noskipws here
  string s;
  while(ss >> s) {
    cout << s; 
  }

  // program exits with only "Thi" printed
  return 0;
}

核心原因

  1. noskipws是流的持久化状态:noskipws不是单次提取的临时设置,一旦通过ss >> noskipws设置,这个标志会一直保留在stringstream的状态中,直到被手动修改。第一个循环结束后,流仍然处于“不跳过空白字符”的模式。
  2. 循环终止时的流位置:第一个循环在i>2时break,此时已经提取了前3个字符(T、h、i),流的下一个待读取字符是原字符串中This后面的空格。
  3. 字符串提取的行为冲突:ss >> s提取字符串的默认逻辑是跳过所有空白字符,直到遇到非空白字符才开始读取。但因为流的noskipws标志仍处于开启状态,跳过空白的行为被禁用了。此时流的第一个待读取字符是空格,>>尝试读取非空白字符失败,导致ss >> s返回false,循环直接终止,没有任何后续输出。

解决办法

  • 方法一:第一个循环结束后,手动恢复流的默认空白跳过状态:
    // 在第二个循环前添加
    ss >> skipws;
    
  • 方法二:避免在循环提取中直接设置noskipws,改为临时设置后恢复:
    // 第一个循环修改为,只在单次提取时临时生效
    while (i <= 2 && ss >> noskipws >> c) { 
      cout << c;
      i++;
    }
    ss >> skipws; // 恢复默认状态
    

内容的提问来源于stack exchange,提问作者Ashkan Arabi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:54:50