我们可以将位写入C中的.bin文件吗?

时间:2019-02-21 09:53:44

标签: c binary

我想将一个字符编码为2位,即:

'A' to 00  
'C' to 01  
'G' to 10  
'T' to 11  

现在,例如,给定一个文件,其内容为ACGT,其大小将为4个字节。

我想读取该文件并将其相应的位写入一个.bin文件,该文件的大小最终将仅为8位(1个字节)。

即:

输入文本文件的内容:ACGT
输出二进制文件内容:00011011

通过这样做,我将尺寸减小了原始尺寸的1/4倍。
可以用C语言实现吗?

1 个答案:

答案 0 :(得分:1)

以下代码演示了您需要执行的操作。它根据您的规范进行编码/解码,但仅在内存中而不在文件中。该代码需要修改以对文件进行编码/解码。

编码字节的格式:

前4个字节(根据平台,为8个字节)包含大尾数(或根据平台的小尾数格式)的编码字符数(“ ACGTA”为5个字符)。之后的字节包含根据您的规范的编码字符。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void encode(const char *input, unsigned char *output)
{
  size_t size = strlen(input);
  memcpy(output, &size, sizeof (size_t));
  output += sizeof(size_t);
  size_t outputindex = 0;

  for (size_t i = 0; i < size; )
  {
    unsigned char byte = 0;

    for (int j = 0; j < 4 && i < size; j++)
    {
      unsigned char value;
      switch (input[i++])
      {
      case 'A':
        value = 0;
        break;
      case 'C':
        value = 1;
        break;
      case 'G':
        value = 2;
        break;
      case 'T':
        value = 3;
        break;
      default:
        printf("Input error, invalid char '%c' encountered\n", input[i - 1]);
        exit(1);
      }

      byte |= (value << ((3 - j) * 2));
    }

end:
    output[outputindex++] = byte;
  }
}

void decode(const unsigned char *input, char *output)
{
  size_t size;
  memcpy(&size, input, sizeof(size_t));
  input += sizeof(size_t);
  size_t inputindex = 0;

  size_t i;
  for (i = 0; i < size;)
  {
    unsigned char ch = input[inputindex++];

    for (int j = 0; j < 4; j++)
    {
      unsigned char b = (ch >> ((3 - j) * 2)) & 0x3;
      output[i++] = "ACGT"[b];
      if (i >= size)
        break;
    }
  }

  output[i] = 0;
}

void printhexencoded(unsigned char *input)
{
  size_t size;
  memcpy(&size, input, sizeof(size_t));
  size = (size + 3) / 4;
  input += sizeof(size_t);

  for (size_t i = 0; i < size; i++)
  {
    printf("%02x", input[i]);
  }
}

int main(void)
{
  const char testdata[] = "ACGTCGTAACGATACTGCTAA";

  printf("Encoding %s\n", testdata);
  unsigned char encodedbytes[100];
  encode(testdata, encodedbytes);

  printf("Encoded bytes in hexadecimal: ");
  printhexencoded(encodedbytes);
  printf("\n");

  char decodedbytes[100];
  decode(encodedbytes, decodedbytes);

  printf("Decoded bytes %s\n", decodedbytes);  

  if (strcmp(testdata, decodedbytes) != 0)
    printf("Test failed.");
  else
    printf("Test succeeded.");    
}

免责声明:此代码未经过测试,根本没有进行边界检查。假设输入中仅包含[ACGT]中的字符,如果遇到其他任何字符,则程序退出。