首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >保存文件字节的最合适的向量类型是什么?

保存文件字节的最合适的向量类型是什么?
EN

Stack Overflow用户
提问于 2016-10-14 18:56:27
回答 3查看 987关注 0票数 7

保存文件字节的最合适的向量类型是什么?

我正在考虑使用int类型,因为位"00000000“(1字节)被解释为0!

目标是将此数据(字节)保存到文件中,并在稍后从该文件中检索。

注意:这些文件包含空字节(以位表示的“00000000”)!

我有点迷路了。帮帮我!

更新I:

要读取该文件,我将使用以下函数:

代码语言:javascript
运行
复制
char* readFileBytes(const char *name){
    std::ifstream fl(name);
    fl.seekg( 0, std::ios::end );
    size_t len = fl.tellg();
    char *ret = new char[len];
    fl.seekg(0, std::ios::beg);
    fl.read(ret, len);
    fl.close();
    return ret;
}

注意:我需要找到一种方法来确保可以从文件中恢复"00000000“位!

备注2:有什么建议可以安全地将这些比特"00000000“保存到文件中?

注释III:当使用char数组时,我在为该类型转换位"00000000“时遇到了问题。

代码片段:

代码语言:javascript
运行
复制
int bit8Array[] = {0, 0, 0, 0, 0, 0, 0, 0};
char charByte = (bit8Array[7]     ) | 
                (bit8Array[6] << 1) | 
                (bit8Array[5] << 2) | 
                (bit8Array[4] << 3) | 
                (bit8Array[3] << 4) | 
                (bit8Array[2] << 5) | 
                (bit8Array[1] << 6) | 
                (bit8Array[0] << 7);

更新II:

遵循@chqrlie的建议。

代码语言:javascript
运行
复制
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <random>
#include <cstring>
#include <iterator>

std::vector<unsigned char> readFileBytes(const char* filename)
{
    // Open the file.
    std::ifstream file(filename, std::ios::binary);

    // Stop eating new lines in binary mode!
    file.unsetf(std::ios::skipws);

    // Get its size
    std::streampos fileSize;

    file.seekg(0, std::ios::end);
    fileSize = file.tellg();
    file.seekg(0, std::ios::beg);

    // Reserve capacity.
    std::vector<unsigned char> unsignedCharVec;
    unsignedCharVec.reserve(fileSize);

    // Read the data.
    unsignedCharVec.insert(unsignedCharVec.begin(),
               std::istream_iterator<unsigned char>(file),
               std::istream_iterator<unsigned char>());

    return unsignedCharVec;
}

int main(){

    std::vector<unsigned char> unsignedCharVec;

    // txt file contents "xz"
    unsignedCharVec=readFileBytes("xz.txt");

    // Letters -> UTF8/HEX -> bits!
    // x -> 78 -> 0111 1000
    // z -> 7a -> 0111 1010

    for(unsigned char c : unsignedCharVec){
        printf("%c\n", c);
        for(int o=7; o >= 0; o--){
            printf("%i", ((c >> o) & 1));
        }
        printf("%s", "\n");
    }

    // Prints...
    // x
    // 01111000
    // z
    // 01111010

    return 0;
}

更新III:

这是我用来写入二进制文件的代码:

代码语言:javascript
运行
复制
void writeFileBytes(const char* filename, std::vector<unsigned char>& fileBytes){
    std::ofstream file(filename, std::ios::out|std::ios::binary);
    file.write(fileBytes.size() ? (char*)&fileBytes[0] : 0, 
               std::streamsize(fileBytes.size()));
}

writeFileBytes("xz.bin", fileBytesOutput);

更新IV:

进一步了解更新III

" to a file

结论:

毫无疑问,"00000000“位(1字节)问题的解决方案是将存储文件字节的类型更改为std::vector<unsigned char>作为朋友的指导。std::vector<unsigned char>是一种通用类型(在所有环境中都存在),并将接受任何八进制(与“更新I”中的char*不同)!

此外,从数组(char)到向量(无符号字符)的转换对于成功至关重要!对于向量,我更安全地、完全独立于其内容来操作数据(在char数组中,我对此有问题)。

非常感谢!

EN

Stack Overflow用户

发布于 2016-10-14 19:06:25

uint8_t是我眼中的赢家:

  • 它正好是8位,或1字节,长;
  • 它没有签名,无需每次输入unsigned
  • 在所有平台上都是完全一样的;
  • 它是一种泛型类型,并不意味着任何特定用途,与char / unsigned char不同,后者与文本字符相关联,即使在技术上可以用于与uint8_t相同的任何用途。

底线:uint8_t在功能上等同于unsigned char,但在源代码中更好地说明这是一些未指定性质的数据。

所以使用std::vector<uint8_t>

#include <stdint.h>使uint8_t定义可用。

正如注释中指出的那样,C++标准将char定义为1字节,严格地说,字节不需要与octet (8位)相同。在这样一个假设的系统上,char仍然存在,长度为1字节,但是uint8_t被定义为8位(octet),因此可能不存在(由于实现上的困难/开销)。因此,从理论上讲,char更易于移植,但uint8_t更严格,并且对预期行为有更广泛的保证。

票数 1
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40050243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档