Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将字节转换为位并将二进制数据写入文件_C++_File_Compression_Byte_Huffman Code - Fatal编程技术网

C++ 将字节转换为位并将二进制数据写入文件

C++ 将字节转换为位并将二进制数据写入文件,c++,file,compression,byte,huffman-code,C++,File,Compression,Byte,Huffman Code,假设我有一个字符数组,chara[8]包含10101010。如果我将此数据存储在.txt文件中,则此文件的大小为8字节。现在我想问的是,如何将这些数据转换成二进制格式,并将其保存在一个文件中,作为8位(而不是8字节),以便文件大小仅为1字节 另外,一旦我将这8个字节转换为一个字节,我应该用哪种文件格式保存输出。txt或.dat或.bin 我正在研究文本文件的哈夫曼编码。我已经将文本格式转换为二进制,即0和1,但当我将此输出数据存储到文件中时,每个数字(1或0)都会占用一个字节而不是一个位。我想要

假设我有一个字符数组,chara[8]包含10101010。如果我将此数据存储在.txt文件中,则此文件的大小为8字节。现在我想问的是,如何将这些数据转换成二进制格式,并将其保存在一个文件中,作为8位(而不是8字节),以便文件大小仅为1字节

另外,一旦我将这8个字节转换为一个字节,我应该用哪种文件格式保存输出。txt或.dat或.bin

我正在研究文本文件的哈夫曼编码。我已经将文本格式转换为二进制,即0和1,但当我将此输出数据存储到文件中时,每个数字(1或0)都会占用一个字节而不是一个位。我想要一个这样的解决方案,每个数字只需要一点

char buf[100];
void build_code(node n, char *s, int len)
{
static char *out = buf;
if (n->c) {
    s[len] = 0;
    strcpy(out, s);
    code[n->c] = out;
    out += len + 1;
    return;
}

s[len] = '0'; build_code(n->left,  s, len + 1);
s[len] = '1'; build_code(n->right, s, len + 1);
}
这就是我如何在哈夫曼树的帮助下构建代码树的方法。及

void encode(const char *s, char *out)
{
while (*s) 
   {
    strcpy(out, code[*s]);
    out += strlen(code[*s++]);
    }
}
这是我编码以获得最终输出的方式。

单向:

/** Converts 8 bytes to 8 bits **/
unsigned char BinStrToNum(const char a[8])
   {
   return(  ('1' == a[0]) ? 128 : 0
          + ('1' == a[1]) ? 64  : 0
          + ('1' == a[2]) ? 32  : 0
          + ('1' == a[3]) ? 16  : 0
          + ('1' == a[4]) ? 8   : 0
          + ('1' == a[5]) ? 4   : 0
          + ('1' == a[6]) ? 2   : 0
          + ('1' == a[7]) ? 1   : 0);
          );
   };
以您提到的任何格式保存;或者发明你自己的

int main()
   {
   rCode=0;
   char *a = "10101010";
   unsigned char byte;
   FILE *fp=NULL;

   fp=fopen("data.xyz", "wb");
   if(NULL==fp)
      {
      rCode=errno;
      fprintf(stderr, "fopen() failed. errno:%d\n", errno);
      goto CLEANUP;
      }

   byte=BinStrToNum(a);
   fwrite(&byte, 1, 1, fp);

CLEANUP:

   if(fp)
      fclose(fp);

   return(rCode);
   }

您可以很容易地将它们转换为一个字节,如下所示:

byte x = (s[3] - '0') + ((s[2] - '0') << 1) + ((s[1] - '0') << 2) + ((s[0] - '0') << 3);

byte x=(s[3]-“0”)+((s[2]-“0”)不完全确定如何以表示值的二进制表示的字符串结束,
但您可以使用标准函数(如)从字符串(任何基)中获取整数值

该函数提供无符号长值,因为您知道您的值在0-255范围内,所以可以将其存储在无符号字符中:

无符号字符v=(无符号字符)(std::strtool(binary_string_value.c_str(),0,2)和0xff)

将其写入磁盘时,可以使用流进行写入

我应该以何种文件格式保存输出?.txt或.dat或.bin

请记住,扩展名(.txt、.dat或.bin)实际上并不强制使用格式(即内容的结构)。该扩展名是一种常用的约定,用于指示您使用的是某种已知格式(在某些操作系统/环境中,它驱动哪个程序最能处理该文件的配置)。因为这是您的文件,所以您可以定义实际格式…并使用您最喜欢的任何扩展名(甚至没有扩展名)命名该文件(或者换句话说,任何最能代表您的内容的扩展名),只要它对您和将要使用您的文件的人有意义

编辑:其他详细信息 假设我们有一个一定长度的缓冲区,您在其中存储字符串“0”和“1”

int codeSize; // size of the code buffer
char *code;   // code array/pointer
std::ofstream file; // File stream where we're writing to.


unsigned char *byteArray=new unsigned char[codeSize/8+(codeSize%8+=0)?1:0]
int bytes=0;
for(int i=8;i<codeSize;i+=8) {
    std::string binstring(code[i-8],8); // create a temp string from the slice of the code
    byteArray[bytes++]=(unsigned char)(std::strtoul(binstring.c_str(),0,2) & 0xff);
}

if(i>codeSize) {
    // At this point, if there's a number of bits not multiple of 8, 
    // there are some bits that have not
    // been writter. Not sure how you would like to handle it. 
    // One option is to assume that bits with 0 up to 
    // the next multiple of 8... but  it all depends on what you're representing.
}

file.write(byteArray,bytes); 
int codeSize;//代码缓冲区的大小
char*code;//代码数组/指针
std::ofstream file;//我们要写入的文件流。
无符号字符*byteArray=新的无符号字符[codeSize/8+(codeSize%8+=0)?1:0]
int字节=0;
用于(int i=8;icodeSize){
//此时,如果有很多位不是8的倍数,
//有些地方还没有
//我一直在写,不知道你想怎么处理。
//一种选择是假设0到
//下一个8的倍数…但这取决于你代表的是什么。
}
file.write(字节数组,字节);

函数将表示位表示的输入8个字符转换为一个字节

char BitsToByte( const char in[8] )
{
    char ret = 0;
    for( int i=0, pow=128;
         i<8;
         ++i, pow/=2;
        )
        if( in[i] == '1' ) ret += pow;
    return ret;
}
char位字节(const char in[8])
{
char-ret=0;
对于(inti=0,pow=128;

I字符是0和1,还是“0”和“1”?一个关于如何构造数据的简短示例会有所帮助。@Edward Well我正在研究文本文件的哈夫曼编码。我已经将文本格式转换为二进制,即0和1,但当我将此输出数据存储在文件中时,每个数字(1或0)需要一个字节而不是一位。我想要一个每个数字只需要一位的解决方案。您想让我共享完整的代码吗?一个简短的自包含示例会很有用。从您的描述很难看出您实际拥有什么。如果您已将数据转换为二进制,则每位不会有一位。@RetiredInja它是“0”和“1”是的概述可能会有所帮助。我刚刚用我的代码编辑了问题内容。请看一看,并建议我怎么做。谢谢。