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

std::wstringstream按块读取数据不完整问题咨询

关于std::wstringstream读取数据不完整的问题分析

嘿,我来帮你捋捋这段代码的问题出在哪:

先看你写的代码:

#include <iostream>
#include <sstream>
int main(int argc, char* argv[]) {
    std::wstringstream buf(L"dsadsadsad dsadsadsad sadsadsadsad sa dsadsadsads dasdsadsa");
    wchar_t sendbuf[5];
    wmemset(sendbuf, 0, 5);
    while (buf.read(sendbuf, 5)) {
        std::wcout << sendbuf;
        wmemset(sendbuf, 0, 5);
    }
    return 0;
}

核心原因

问题就出在while (buf.read(sendbuf, 5))这个循环条件上。std::basic_istream::read()的返回值规则是:只有当它成功读取到你指定的全部字符数(这里是5个)时,才会返回一个“真值”。如果流里剩下的字符不足5个,read()就会失败,循环直接终止,那些没读完的剩余字符就被彻底忽略了。

打个比方,假设你的字符串总共有47个宽字符,47除以5是9个完整的块(45个字符),还剩2个字符。这时候循环会执行9次,然后第10次read()尝试读5个但只能读到2个,返回false,循环结束,那2个字符就没机会被输出了。

解决办法

要把所有字符都输出,咱们得在循环结束后,检查流里有没有剩下没读完的字符,然后把它们也打印出来。修改后的代码如下:

#include <iostream>
#include <sstream>
int main(int argc, char* argv[]) {
    std::wstringstream buf(L"dsadsadsad dsadsadsad sadsadsadsad sa dsadsadsads dasdsadsa");
    wchar_t sendbuf[5];
    // 先读取所有完整的5字符块
    while (buf.read(sendbuf, 5)) {
        std::wcout << sendbuf;
    }
    // 处理剩余的不足5个的字符
    std::streamsize remaining = buf.gcount();
    if (remaining > 0) {
        sendbuf[remaining] = L'\0'; // 手动添加宽字符串终止符,避免乱码
        std::wcout << sendbuf;
    }
    return 0;
}

补充说明

  • buf.gcount()这个函数会返回上一次输入操作(也就是最后一次read())实际读取到的字符数量,哪怕没读满你指定的5个。
  • 最后一定要给剩余字符加L'\0',因为sendbuf是字符数组,std::wcout输出的时候需要看到终止符才会停止,不然可能会输出内存里的垃圾数据。
  • 之前的wmemset其实可以去掉,因为每次read()会覆盖数组里的旧内容,最后我们也手动加了终止符,不过如果习惯保留也完全没问题,不影响功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:12:32