我知道下面的功能:
size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
它只能逐字节读取,我的目标是能够一次读取12位然后将它们放入一个数组中。任何帮助或指示将不胜感激!
答案 0 :(得分:5)
添加到第一个注释,您可以尝试一次读取一个字节(声明一个char变量并在那里写入),然后使用按位运算符>>和<<一点一点地读。在此处阅读更多内容:http://www.cprogramming.com/tutorial/bitwise_operators.html
答案 1 :(得分:2)
从a_file
文件指针读取前两个字节并检查最小或最大字节中的位 - 取决于平台的endianness(x86是little-endian) - 使用bitshift运算符
您无法将位真正放入数组中,因为没有位数据类型。而不是将1和0保持在数组中,这是低效的,将两个字节保持在两个元素(例如,类型为unsigned char *
)并写入函数以将这两个字节映射到一个似乎更便宜4096(2 ^ 12)个感兴趣的值。
作为一个复杂因素,在后续读取中,如果你希望每12位通过指针fread
,你只能读取一个字节,使用前面的剩余位读取以构建新的12位值。如果没有剩余部分,则需要读取两个字节。
您的映射函数需要解决第二种情况,即从先前的读取使用位,因为这两个字节需要不同的映射。为了有效地做到这一点,可以使用读计数器上的模数在两个映射之间进行交换。
答案 2 :(得分:2)
我已经实现了几种逐位读/写文件的方法。他们是section four of the python tutorial might also be helpful。无论您的用例是否可行,您都必须自己决定。我试图制作最易读,最优化的代码,而不是经验丰富的C开发人员(目前)。
在内部,它使用“bitCursor”来存储有关尚未适合整个字节的先前位的信息。它有哪些数据字段: d 存储数据和 s 存储大小,或存储在游标中的位数。
您有四个功能:
评论中提供了更多信息。玩得开心!
编辑:Here今天,当我说我假设Little Endian时! :P哎呀!我总是很高兴知道我还有多少菜鸟; D。
答案 3 :(得分:1)
许多年前,我在C中为霍夫曼编码器编写了一些I / O例程。这需要能够读取和写入比特的粒度而不是字节。我创建了类似于read(2)和write(2)的函数,可以要求(例如)从流中读取13位。例如,为了编码,字节将被馈送到编码器中,并且可变数量的比特将出现在另一侧。我有一个简单的结构,其中一个位指针指向正在读取或写入的当前字节。每次它结束时,它都会将完成的字节刷新并将指针重置为零。不幸的是,代码早已不复存在,但是将开源霍夫曼编码器分开并看看问题是如何解决的可能是一个想法。类似地,base64编码需要3个字节的数据并将它们变为4(反之亦然)。
答案 4 :(得分:1)
读取2个字节并执行逐位操作将在下次读取后完成第二个字节以后应用逐位操作将返回您的预期。 。 。
答案 5 :(得分:0)
对于你的问题你可以看到这个演示程序读取2byte但实际信息只有12位。除了这种类型的东西使用它有点明智的访问。
fwrite()是一个标准库函数,它将size参数作为byte和int类型。所以你不可能完全读取12bit。如果你创建的文件也创建如下所示如下所示它解决了你的问题。
如果该文件是非您写的特殊文件,那么请遵循为该文件提供的标准来阅读我认为他们也只是这样写的。或者你可以提供我可以帮助你的理由。
#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);
}