我知道下面的功能:
size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
它只能逐字节读取,我的目标是一次读取 12 位,然后将它们放入数组中。任何帮助或指示将不胜感激!
添加到第一个注释,您可以尝试一次读取一个字节(声明一个 char 变量并在那里写入),然后使用按位运算符 >> 和 << 逐位读取。在这里阅读更多:http ://www.cprogramming.com/tutorial/bitwise_operators.html
许多年前,我用 C 语言为 Huffman 编码器编写了一些 I/O 例程。这需要能够在位而不是字节的粒度上进行读写。我创建了类似于 read(2) 和 write(2) 的函数,可以要求(比如说)从流中读取 13 位。例如,为了编码,字节将被输入编码器,可变数量的比特将出现在另一端。我有一个简单的结构,其中有一个指向正在读取或写入的当前字节的位指针。每次它结束时,它都会刷新完成的字节并将指针重置为零。不幸的是,该代码早已不复存在,但拆开一个开源 Huffman 编码器并看看那里的问题是如何解决的可能是一个想法。类似地,base64 编码需要 3 个字节的数据并将它们转换为 4 个字节(反之亦然)。
我已经实现了几种方法来一点一点地读/写文件。他们在这里。无论它对您的用例是否可行,您都必须自己决定。我已经尝试制作最易读、最优化的代码,而不是经验丰富的 C 开发人员(目前)。
在内部,它使用“bitCursor”来存储有关尚未适合完整字节的先前位的信息。它具有 who 数据字段:d存储数据,s存储大小,或存储在游标中的位数。
你有四个功能:
评论中提供了更多信息。玩得开心!
编辑:今天我知道,当我这样做时,我假设是小端!:P 哎呀!意识到我仍然是一个菜鸟总是很高兴;D。
编辑:GNU 的二进制文件描述符。
从文件指针中读取前两个字节a_file
并检查最小或最大字节中的位 - 取决于平台的字节序(x86 是小字节序) - 使用位移运算符。
您不能真正将位放入数组中,因为没有位的数据类型。与其将 1 和 0 保存在一个效率低下的数组中,不如将两个字节保存在一个二元素数组(例如 type unsigned char *
)中并编写函数将这两个字节映射到 4096 之一(2^ 12) 利益价值。
复杂的是,在后续读取中,如果您希望fread
每 12 位通过指针,您将只读取一个字节,使用前一次读取的剩余位来构建一个新的 12 位值。如果没有剩余,则需要读取两个字节。
您的映射函数需要解决第二种情况,即使用先前读取的位,因为这两个字节需要不同的映射。为了有效地做到这一点,可以使用读取计数器上的模数在两个映射之间进行交换。
读取 2 个字节并执行按位操作将在下次读取第 2 个字节时完成,应用按位操作将返回您预期的结果。. . .
对于您的问题,您可以看到这个演示程序,它读取 2 字节,但实际信息只有 12 位。除了这种类型的东西,它还用于按位访问。
fwrite() 是一个标准库函数,它将 size 参数作为字节和 int 类型。所以不可能完全 12 位读取。如果您创建的文件然后创建如下所示,并如下读取它可以解决您的问题。
如果该文件是不是由您编写的特殊文件,那么请按照为该文件提供的标准进行读取,我认为他们也只能这样写。或者您可以提供我可以帮助您的确切信息。
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data:12;
}NODE;
int main()
{
FILE *fp;
fp=fopen("t","w");
NODE.data=1024;
printf("%d\n",NODE.data);
fwrite(&NODE,sizeof(NODE),1,fp);
NODE.data=0;
NODE.data=2048;
printf("%d\n",(unsigned)NODE.data);
fwrite(&NODE,sizeof(NODE),1,fp);
fclose(fp);
fp=fopen("t","r");
fread(&NODE,sizeof(NODE),1,fp);
printf("%d\n",NODE.data);
fread(&NODE,sizeof(NODE),1,fp);
printf("%d\n",NODE.data);
fclose(fp);
}