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

时间:2016-10-14 18:56:28

标签: c++ visual-c++ byte bit

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

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

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

注意:文件包含空字节(以位为“00000000”)!

我在这里有点失落。帮我! = D谢谢!

更新I:

要读取我正在使用此功能的文件:

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;
}

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

注意II:有关将这些位“00000000”保存到文件的安全方法的建议吗?

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

代码段:

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建议。

#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:

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

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:

进一步阅读 UPDATE III

c++ - Save the contents of a "std::vector<unsigned char>" to a file

结论:

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

此外,从数组(char)更改为vector(unsigned char)对于成功至关重要!使用向量我可以更安全地操作我的数据并完全独立于其内容(在char数组中我遇到了问题)。

非常感谢!

3 个答案:

答案 0 :(得分:3)

使用std::vector<unsigned char>。不要使用std::uint8_t:它不会存在于没有8位本机硬件类型的系统上。 unsigned char将永远存在;它通常是硬件支持的最小可寻址类型,并且它必须至少为8位宽,因此如果您以8位字节进行广告投放,它将处理您需要的位。

如果你真的非常非常喜欢固定宽度类型,你可以考虑std::uint_least8_t,它将永远存在,至少有8位,或者std::uint_fast8_t,它至少也是八位。但char类型中的文件I / O流量,以及混合char及其变体与模糊指定的“最少”和“快速”类型可能会让人感到困惑。

答案 1 :(得分:2)

您的代码中存在3个问题:

  • 您使用char类型并返回char *。然而,返回值不是正确的C字符串,因为您没有为'\0'终止符分配额外的字节,也不为null终止它。

  • 如果文件可能包含空字节,则应该使用类型unsigned charuint8_t来明确表示数组不包含文本。

  • 您不会将数组大小返回给调用者。调用者无法判断数组有多长。您应该使用std::vector<uint8_t>std::vector<unsigned char>而不是使用new分配的数组。

答案 2 :(得分:1)

uint8_t是我眼中的赢家:

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

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

所以请使用#include <stdint.h> uint8_t char定义{/ 1}}。

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