繁体   English   中英

如何使用 std::string 以正确的方式存储字节(无符号字符)?

[英]How to use std::string to store bytes (unsigned chars) in a right way?

我正在编写 LZ77 压缩算法,但无法在字符串中存储无符号字符。 要压缩任何文件,我使用它的二进制表示,然后将其作为chars (因为 1 个字符等于 1 个字节,afaik)读取到std::string 使用chars一切正常。 但是经过一段时间的谷歌搜索后,我了解到char并不总是 1 个字节,所以我决定将它换成unsigned char 事情开始变得棘手:

  • 压缩普通 .txt 时,一切都按预期工作,我在解压前后得到相同的文件(我认为应该如此,因为我们基本上在字节转换前后处理文本)
  • 但是,当尝试压缩 .bmp 时,与输入文件相比,解压缩文件丢失了 3 个字节(尝试将无符号字符保存到 std::string 时我丢失了这 3 个字节)

所以,我的问题是 - 有没有办法将无符号字符正确保存到字符串中?

我尝试使用typedef basic_string<unsigned char> ustring并将所有相关函数交换为与unsigned char一起使用的基本替代方法,但我仍然丢失了 3 个字节。

更新:我发现 3 个字节(符号)丢失不是因为 std::string,而是因为std::istream_iterator (我用它代替std::istreambuf_iterator )来创建无符号字符字符串(因为std::istreambuf_iterator的参数是字符,而不是无符号字符)

那么,有没有解决这个特定问题的方法?

例子:

std::vector<char> tempbuf(std::istreambuf_iterator<char>(file), {}); // reads 112782 symbols

std::vector<char> tempbuf(std::istream_iterator<char>(file), {}); // reads 112779 symbols

示例代码:

void LZ77::readFileUnpacked(std::string& path)

{


std::ifstream file(path, std::ios::in | std::ios::binary);

if (file.is_open())
{
    // Works just fine with char, but loses 3 bytes with unsigned
    std::string tempstring = std::string(std::istreambuf_iterator<char>(file), {});
    file.close();
}
else
    throw std::ios_base::failure("Failed to open the file");
}

所有形式的char (以及std::byte ,它与unsigned char同构)始终是系统支持的最小可能类型。 C++ 标准定义sizeof(char)及其变体应始终为 1。

“一个”什么? 那是实现定义的。 但是系统中的每种类型的sizeof(char)都是sizeof(char)倍数。

所以你不应该太担心char不是一个字节的系统。 如果您在CHAR_BITS不是 8 的系统下工作,那么该系统根本无法直接处理 8 位字节。 因此unsigned char为此目的不会有任何不同/更好。


至于你的问题的细节, istream_iteratoristreambuf_iterator迭代器istreambuf_iterator根本的不同。 后者的目的是允许迭代器访问作为值序列的实际流。 istream_iterator<T>的目的是允许访问流,就像通过执行带有T值的operator >>调用的重复序列一样。

因此,如果您正在执行istream_iterator<char> ,那么您是在说您想像读取流一样读取stream >> some_char; 每个迭代器访问的变量。 直接访问流的字符实际上并不是同构的。 具体来说, operator>>这样的FormattedInputFunctions可以执行诸如跳过空格之类的operator>> ,具体取决于您设置流的方式。

istream_iterator正在使用operator>>读取,它通常会跳过空格作为其功能的一部分。 如果你想禁用这种行为,你必须这样做

#include <ios>

file >> std::noskipws;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM