为何boost::basic_array_source读取值与boost::back_insert_device写入值不一致?
问题原因
1. 写入逻辑的格式化输出特性
你使用流的<<运算符写入int类型的1、2、3时,该运算符属于格式化输出接口,C++标准流默认会将整型数值转换为对应的ASCII字符写入目标容器。因此你实际写入std::vector<char>的是字符'1'、'2'、'3',对应的ASCII编码值恰好是十进制的49、50、51。
你之前循环打印char类型的entry时,std::cout会将char值作为字符渲染输出,所以能看到1、2、3的显示效果,但容器底层存储的就是ASCII编码值。
2. 读取接口的返回值特性
你调用stream2.get()时,该接口的返回值类型为int:
- 正常读取到字符时,会将字符转换为
unsigned char再提升为int返回,因此直接打印就会得到ASCII码的十进制数值 - 读取到流末尾时会返回
EOF(值为-1),这就是你看到末尾-1的来源
3. 循环写法的冗余问题
你使用while (!stream2.eof())作为循环判断条件的写法存在逻辑缺陷:eof()标记是在读取操作失败后才会被置位,因此会多执行一次读取操作,直接输出了代表EOF的-1。
修正方案
根据你的使用场景可以选择两种修复方式:
方案1:读写字符形态的数字
如果你的预期就是存储字符形式的1、2、3,只需要修改读取逻辑,将get()返回的int值转为char后输出,同时调整循环判断条件避免读到EOF:
int ch; while ((ch = stream2.get()) != EOF) { std::cout << "Read entry " << char(ch) << std::endl; }
方案2:读写原始二进制数值
如果你的预期是存储整型数值的原始二进制数据,不要使用格式化的<</>>接口,改用二进制读写接口:
写入侧修改:
int val1 = 1, val2 = 2, val3 = 3; stream.write(reinterpret_cast<const char*>(&val1), sizeof(val1)); stream.write(reinterpret_cast<const char*>(&val2), sizeof(val2)); stream.write(reinterpret_cast<const char*>(&val3), sizeof(val3));
读取侧修改:
int read_val; while (stream2.read(reinterpret_cast<char*>(&read_val), sizeof(read_val))) { std::cout << "Read entry " << read_val << std::endl; }
内容的提问来源于stack exchange,提问作者Benjamin Bihler
相关产品推荐
相关产品推荐

