我有一个由 0 和 1 组成的字符串。如何将这些 0 和 1 以二进制格式存储在文件中?



考虑字符串"010010101"。我想把上面的字符串以二进制格式存储在一个文件中。我想这样做是因为当我执行以下代码时:

    ofstream out("file.txt");
    out << string;

文件大小太大。我想通过在文件中以二进制格式存储0和1来减小文件大小。

您可以将字节写入文件

例如

#include <fstream>
...
char buffer[100];
ofstream myFile ("data.bin", ios::out | ios::binary);
myFile.write (buffer, 100);

现在我们知道如何写入字节,我们只需要知道如何将字符串转换为要写入的字节值。

假设您的字符串不是用unicode编码的,我们可以简单地使用ascii表来发现"1"表示数值49,"0"表示数值48。

有了这些知识,您可以在字符串的每8个字符中迭代,每个"1"或"0"的子字符串48将为您提供数值。然后将8个数字一起移位,直到得到字节。如果少于8个字符,则需要放置前导零。

我懒得写代码,但我想有了这些知识,你应该能够写一个很好的工作算法。

只需使用此函数将'0''1'字符的字符串转换为压缩二进制字符串:

string pack_bin (string const & s)
{
    string ret;
    ret.reserve ((s.size() + 7) / 8);
    for (unsigned i = 0; i < s.size(); )
    {
        char c = 0;
        for (unsigned j = 0; j < 8; ++j, ++i)
            c = (c << 1) | ((s[i] != '0') ? 1 : 0);
        ret += c;
    }
    return ret;
}

反过来:

string unpack_bin (string const & s)
{
    string ret;
    ret.reserve (s.size() * 8);
    for (unsigned i = 0; i < s.size(); ++i)
        for (int j = 7; j >= 0; --j)
            ret += ((s[i] & (1 << j)) ? '1' : '0');
    return ret;
}

注意以下内容:

  • 如果字符串的长度不是8的倍数,则必须将长度与生成的字符串一起存储,以便能够恢复您所拥有的确切字符串。否则,解压缩后的字符串末尾将有额外的零
  • 最好将结果字符串写入二进制文件,即ofstream out("file.txt", ios:binary);

你可以像这样使用上面的例程:

// To write:
ofstream out ("file.txt", ios::binary);
out << pack_bin(str);
// To read back:
ifstream in ("file.txt", ios::binary);
string s;
in >> s;
s = unpack_bin (s);

相关内容

  • 没有找到相关文章

最新更新