gpt4 book ai didi

c++ - 跨平台UTF-8 char文件数据编码/解码

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:09:57 25 4
gpt4 key购买 nike

我使用数据结构对二进制文件进行编码,其中一个属性是用于 UTF-8 支持的 wchar_t 类型。

每个结构看起来像这样:

 struct DataBlock{

wchar_t charcode;
int width;
int height;
///etc

}

编码发生在 wchar_t 大小为 2 个字节的 Windows 上。

文件的解码发生在大小为 4 字节的 Linux 上。因此在 Linux 端读取的 charcode 值是错误的。

在不使用 3rd party libs 的情况下解决该差异的最佳方法是什么?对于 UTF?是否可以对 charcode 进行编码,例如在 win 上编码为“int”数据类型,然后在 Linux 上将其转换为 wchar_t?

最佳答案

编写二进制结构本质上是不可移植的。坏事几乎无处不在:

  • 对于任何大于 char 的类型,您都可能遇到字节顺序问题
  • 对于任何短于 8 字节的类型,您都可能遇到对齐问题 - 即使这可以通过支持它的体系结构和编译器上的 #pragma 来缓解。

你应该避免这种情况,而是使用一种 marshalling ,这是一种明确且独立于体系结构的方式的序列化。例如:

  • wchar_t charcode - 假设您的 charcode 永远不会使用超过 2 个字节,您明确地将其转换为 char[2](事实上我m 强制使用 2 字节大端表示法):

    code[0] = (charcode >> 8) & 0xFF;
    code[1] = charcode & 0xFF;
  • int - 知道您是否需要 2、4 或 8 个字节来表示 width 的任何值高度 ;假设它是 4 (int32_tuint32_t)

    code[0] = (width >> 24) & 0xFF;
    code[1] = (width >> 16) & 0xFF;
    code[2] = (width >> 8) & 0xFF;
    code[3] = width & 0xFF;

因此,您在具有确定大小的 char 数组中明确定义了 struct DataBlock 的转换。现在您确实拥有了可移植到任何网络、体系结构或编译器上的东西。当然,您已经明确编写了用于编码和解码的 2 例程,但这是我所知道的拥有可移植二进制结构的唯一方法。

希望htonx函数可以帮到你。它们明确采用 16 位或 32 位整数,并强制以 网络(大端)顺序进行转换。来自 Linux 手册页:

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

htonl() 函数将无符号整数 hoSTLong 从主机字节顺序转换为网络字节顺序。

htons() 函数将无符号短整数 hostshort 从主机字节顺序转换为网络字节顺序。

ntohl() 函数将无符号整数 netlong 从网络字节顺序转换为主机字节顺序。

ntohs() 函数将无符号短整数 netshort 从网络字节顺序转换为主机字节顺序。

这样,您就可以直接编写结构的字段:

long l = htonl(data.charcode); // or htons if you only need 16 bits
fwrite(&l, sizeof(long), 1, fdout); // sizeof(short) if you used 16 bits

阅读也一样:

long l;
fread(&l, sizeof(long), 1, fdin);
data.charcode = ntohl(l);

这个函数在类 Unix 系统下已经定义了很长时间,并且似乎在最近版本的 Windows 编译器上定义。

当然,如果您绝对确定您只会使用小端架构,您甚至可以不转换为字节序。但请务必在您的文档中优先使用红色闪烁字体来纠正...

关于c++ - 跨平台UTF-8 char文件数据编码/解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28796471/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com