Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将无符号16位整数存储到文件的最有效方法_C_Dictionary_Binary_Compression_Ascii - Fatal编程技术网

C 将无符号16位整数存储到文件的最有效方法

C 将无符号16位整数存储到文件的最有效方法,c,dictionary,binary,compression,ascii,C,Dictionary,Binary,Compression,Ascii,我正在用C语言制作一个字典压缩程序,最大字典大小为64000。因此,我将条目存储为16位整数 我目前正在做的事情: 为了对“a”进行编码,我得到了它的ASCII值97,然后将这个数字转换成16位整数97的字符串表示形式。因此,我最终将“0000000001100001”编码为“a”,这显然在短期内不会节省太多空间 我知道,这种算法的更有效版本将从更小的整数大小开始(在需要更多之前,存储位会更少),但我想知道是否有更好的方法来实现这两个目标 将整数“97”转换为固定长度的ASCII字符串,该字符串

我正在用C语言制作一个字典压缩程序,最大字典大小为64000。因此,我将条目存储为16位整数

我目前正在做的事情: 为了对“a”进行编码,我得到了它的ASCII值97,然后将这个数字转换成16位整数97的字符串表示形式。因此,我最终将“0000000001100001”编码为“a”,这显然在短期内不会节省太多空间

我知道,这种算法的更有效版本将从更小的整数大小开始(在需要更多之前,存储位会更少),但我想知道是否有更好的方法来实现这两个目标

  • 将整数“97”转换为固定长度的ASCII字符串,该字符串可存储16位数据(97为x位,46347为x位)

  • 写入只能存储1和0的文件。因为事实上,我好像在向一个文本文件中写入16个ascii字符,每个字符都是8位…所以这对原因没有多大帮助,是吗

  • 请让我知道,如果我可以更清楚地在任何方式。我对这个网站很陌生。谢谢大家!

    编辑:据我所知,如何储存我的词典完全取决于我自己。我只知道我需要能够轻松地读回编码文件并从中获取整数


    另外,我只能包含stdio.h、stdlib.h、string.h和我为程序编写的头文件。

    您考虑的是在保存数字时使用ASCII字符,这是完全不必要的,也是最低效的

    最节省空间的方法(不使用复杂的算法)是将数字的字节转储到文件中(位数必须取决于您要保存的最大位数。或者将多个文件用于8位、16位等)


    然后,当你读取文件时,你知道你的数字是以x位为单位的,所以你只需一个接一个地或以一个大数据块的形式读取它们,然后将数据块制作成一个与x位匹配的数组。

    请忽略那些建议你“直接写入文件”的人。这方面存在许多问题,最终属于“整数表示”的范畴。似乎有一些令人信服的理由可以使用
    fwrite
    或其他方法将整数直接写入外部存储器,这里有一些确凿的事实

    瓶颈是外部存储控制器。如果您正在编写网络应用程序,则要么是外部存储控制器,要么是网络。因此,将两个字节作为单个
    fwrite
    写入,或者作为两个不同的
    fputc
    写入,速度应该大致相同,前提是您的内存配置文件适合您的平台。您可以调整使用
    setvbuf
    时,
    文件*
    使用的缓冲区量(注意:必须是二的幂),因此我们总是可以根据分析器告诉我们的内容对每个平台进行微调,尽管这些信息可能会通过温和的建议优雅地飘到标准库的上游,对其他项目也很有用

    当前计算机之间的基本整数表示不一致。假设您使用system X直接将
    无符号整数
    s写入一个使用32位整数和大端数表示的文件,那么在system Y(使用16位整数和小端数表示)或sy上读取该文件时会遇到问题stem Z使用64位整数,混合endian表示和32位填充位。如今,我们有15年前的计算机组合,人们用它来折磨自己,使自己变得强大。小型SOC、智能手机和智能电视、游戏机和PC,所有这些都有自己的怪癖,不属于标准C的范畴,尤其是智能手机h涉及整数表示、填充等

    C开发时考虑到了抽象,它允许您以可移植的方式表达算法,这样您就不必为每个操作系统编写不同的代码!下面是一个可移植地读取四个十六进制数字并将其转换为
    无符号int
    值的示例:

    unsigned int value;
    int value_is_valid = fscanf(fd, "%04x", &value) == 1;
    assert(value_is_valid); // #include <assert.h>
                            /* NOTE: Actual error correction should occur in place of that
                             *       assertioon
                             */
    
    假设您的
    unsigned int
    值占用两个字节,下面是我如何使用big-endian表示法可移植地读取这两个字节:

    int hi = fgetc(fd);
    int lo = fgetc(fd);
    unsigned int value = 0;
    assert(hi >= 0 && lo >= 0); // again, proper error detection & handling logic should be here
    value += hi & 0xFF; value <<= 8;
    value += lo & 0xFF;
    
    也许你对little endian更感兴趣。最妙的是,代码其实没什么不同。这里是输入:

    int lo = fgetc(fd);
    int hi = fgetc(fd);
    unsigned int value = 0;
    assert(hi >= 0 && lo >= 0);
    value += hi & 0xFF; value <<= 8;
    value += lo & 0xFF;
    
    对于大于两个字节的任何内容(即
    长无符号
    长有符号
    ),您可能希望
    fwrite((char unsigned[]){value>>24,value>>16,value>>8,value},1,4,fd);
    或类似的东西来简化样板文件。考虑到这一点,形成预处理器宏似乎并不滥用:

    #define write(fd, ...) fwrite((char unsigned){ __VA_ARGS__ }, 1, sizeof ((char unsigned) { __VA_ARGS__ }), fd)
    
    我想人们可能会把这看作是在两个邪恶中选择更好的:预处理器滥用或上面代码中的神奇数字
    4
    ,因为现在我们可以
    写入(fd,value>>24,value>>16,value>>8,value)
    没有硬编码的
    4
    但是一句话对新手来说:副作用可能会引起头痛,所以不要在
    write
    的参数中引起任何形式的修改、写入或全局状态更改


    好的,这是我今天对这篇文章的更新…社交延迟的极客现在退出。

    “将无符号16位整数存储到文件中的最有效方法”-
    write(fd,&the_Integer,sizeof(the_Integer))
    跳过ASCII转换。2字节的整数应该在文件中占2字节。我想你根本不想让这个字典平台独立?如果是这样,在存储之前运行你要存储的
    uint16\u t
    值,在读回它们时运行。虽然不是标准的一部分库,这些是POSIX.1-2001的一部分,可能在您的实现中提供
    int lo = fgetc(fd);
    int hi = fgetc(fd);
    unsigned int value = 0;
    assert(hi >= 0 && lo >= 0);
    value += hi & 0xFF; value <<= 8;
    value += lo & 0xFF;
    
    fputc(value & 0xFF, fd);
    fputc((value >> 8) & 0xFF, fd);
    
    #define write(fd, ...) fwrite((char unsigned){ __VA_ARGS__ }, 1, sizeof ((char unsigned) { __VA_ARGS__ }), fd)