【发布时间】:2021-06-03 16:25:00
【问题描述】:
你好,我有一个位置列表,如存储在链接列表中的图像中所述。每个节点都有一个大小为 2 的无符号字符(代码中的 chessPos)——第一个位置代表一行,第二个位置代表一列。例如第一个节点:row = 'C', col = '5' 等等。该列表通过我不需要构建它的函数传递。
当每行或每列以 3 位写入时,我需要将数据写入二进制文件。所以“C”将被写为 010,“5”之后将被写为 100(写入的 3 位代表行/列 -1,这就是为什么“5”由 100 表示,即二进制的 4)。
困难在于每个字节都是 8 位,每次我将一个字节写入文件时,它都包含 6 位代表一行和一个列,以及下一个字节的 2 位。
我怎样才能让它工作?
谢谢
这是我目前的代码:
typedef char chessPos[2];
typedef struct _chessPosArray {
unsigned int size;
chessPos* positions;
}chessPosArray;
typedef struct _chessPosCell {
chessPos position;
struct _chessPosCell* next;
}chessPosCell;
typedef struct _chessPosList {
chessPosCell* head;
chessPosCell* tail;
}chessPosList;
void function_name(char* file_name, chessPosList* pos_list)
{
FILE* file;
short list_len;
int i = 0;
unsigned char row, col, byte_to_file, next_byte;
chessPosCell* curr = pos_list->head;
file = fopen(file_name, "wb"); /* open binary file to writing */
checkFileOpening(file);
while (curr != NULL)
{
row = curr->position[0] - 'A' - 17; /* 'A' ---> '1' ---> '0' */
col = curr->position[1] - 1; /* '4' ---> '3' */
if (remain < 6)
{
curr = curr->next;
remain += 8;
}
if (i > 1)
{
i = 0;
}
if (curr->next != NULL)
{
next_byte = curr->next->position[i] >> (remain - 7);
byte_to_file = ((row << (remain - 3)) | (col << (remain - 6))) | (next_byte);
i++;
}
else
{
byte_to_file = ((row << (remain - 3)) | (col << (remain - 6)));
}
fwrite(&byte_to_file, sizeof(unsigned char), 1, file);
remain -= 6;
}
【问题讨论】:
-
您目前所拥有的究竟是什么问题?
-
您需要将所有输出缓存在一个字节数组(
unsigned char的数组或分配块)中,并在完成后将其逐字节写入文件。无法将少于一个字节的内容写入文件。换句话说,在将字节写入文件之前,您需要在每个字节中进行所有位打包。 -
如果你真的一次需要三个位,你必须将它们编组为一组字节。您至少需要三个字节(24 位)才能与位和字节保持一致。
-
我怀疑文件大小真的会成为一个很大的问题。我只是将每个位置写成一个完整的字节(浪费 5 位)。但这使得它易于阅读和写作。必要时担心效率,但先让事情变得简单。
-
除非您尝试遵守现有的数据格式,否则这听起来像是过早优化的情况。您的位置列表中有多少条目,与为每个位置使用
char相比,通过节省 5 位/位置您真正可以获得多少?
标签: c binaryfiles bit-shift