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

标签 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语言可以实现吗?

最佳答案

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

编码字节格式:

前 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]集合中的字符,如果遇到任何其他字符,则程序退出。

关于我们可以用 C 将位写入 .bin 文件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54804107/

相关文章:

vba - 如何使用vba加减二进制数?

ios - 生成 xcframework 库时 xcodebuild 错误 "binaries with multiple platforms are not supported"

java - 我的二进制转换器的简要说明

c# 将二进制数据读取到字符串中

c - Ada 将记录数组传递给 c 函数

c - 在 C 中自动将值复制到指针

c - 将数据存储在 EEPROM、微 Controller 中

c - 如何在二进制 *.dat 文件中存储或打印信息? C编程

javascript - 有效地计算 JavaScript 中整数的位数

c - 使用 fprintf 写入文件