将位写入C中的文件

时间:2012-11-06 14:04:49

标签: c file binary

我有这个字符串:" 101" 我想把它写成一个文件,用C语言,而不是文本:" 101"所以8位x char。但是直接使用字符串作为位:位" 1",位" 0"和#34; 1",以便文件为3位。

可能吗? 我在网上搜索过,我试着这样做:

char c[25] = "101";
FILE *binFile = fopen("binFile.bin", "wb");
int x = atoi(c);
fwrite(&x, sizeof(x), 1, binFile);

但最后,当我验证文件的字节时,Windows告诉我它是4bytes文件!而不是3bits!

如果有可能,我怎么能这样做?非常感谢。

5 个答案:

答案 0 :(得分:33)

所有文件系统¹以字节为单位处理文件(并以更大的粒度分配存储空间,最少512字节)。你无法获得 3位长的文件。

你能做的最好就是用掉一整个字节,但忽略其中的5位。要做到这一点(假设数字总是适合一个字节),将输入字符串转换为整数类型:

long l = strtol(c, 0, 2);

然后得到它最不重要的字节:

unsigned char b = l & 0xffl;

并将其写入文件:

fwrite(&b, 1, 1, binFile);

¹好吧,也许不是全部。某些研究人员可能会在某些地方尝试使用比特大小的文件系统。我不知道。

答案 1 :(得分:14)

您的输出文件长度为4个字节,因为您正在向文件写入int。在大多数平台上,int的大小为4个字节。

您一次不能写少于1个字节。

答案 2 :(得分:6)

你可以做的是把它写成位(3)并用0填充一个字节。 但是,您还需要以实际使用的位数(或最后一个字节的位数)开始(或结束)。

E.g。 (使用第一个字节作为长度):

00000011   -> 3, meaning from the last (and only byte in this case, 
              only the first 3 bits are used)
10100000   -> 101 is the string, other 5 bits are 0, just use for padding

在这种情况下,第一个(长度)字节的开销为50%,字符串越长,当然开销百分比越少。

答案 3 :(得分:5)

关于你的方法的2个注释:

  1. [现代]计算机无法在内存中处理少于1个字节,因此您无法将单个位写入磁盘。

    此外,文件系统通常以文件适合的块(512字节,1Kb,...)分配空间。因此,如果您有一个500字节的文件,实际上您将丢失512字节的磁盘空间。

  2. atoi()不会从字符串转换为二进制数字,而是转换为整数。您实际上正在撰写0b1100101,即0d101。你应该先进行转换。类似的东西:

    char b = 0;
    for (int i=0; c[i]!=NULL; i++) 
    {
        b = ((b<<1) | atoi(c[i]));
    }
    

答案 4 :(得分:3)

您没有写入位101,而是写入十进制数101的二进制值,即1100101。由于fread的大小为sizeof(x)字节,因此您的文件长度为sizeof(x)个字节。