c - 在 C 代码中写入和读取 long int 值

标签 c io long-integer

我正在研究一种可以在多种不同操作系统和计算机中写入和读取的文件格式。其中一些计算机应该是 x86 机器,其他计算机应该是 x86-64。可能存在其他一些处理器,但我目前并不关心它们。

这个文件格式应该包含几个数字,可以这样读:

struct LongAsChars{
    char c1, c2, c3, c4;
};

long readLong(FILE* file){
    int b1 = fgetc(file);
    int b2 = fgetc(file);
    int b3 = fgetc(file);
    int b4 = fgetc(file);
    if(b1<0||b2<0||b3<0||b4<0){
        //throwError
    }

    LongAsChars lng;
    lng.c1 = (char) b1;
    lng.c2 = (char) b2;
    lng.c3 = (char) b3;
    lng.c4 = (char) b4;

    long* value = (long*) &lng;

    return *value;
}

写成:

void writeLong(long x, FILE* f){
    long* xptr = &x;
    LongAsChars* lng = (LongAsChars*) xptr;
    fputc(lng->c1, f);
    fputc(lng->c2, f);
    fputc(lng->c3, f);
    fputc(lng->c4, f);
}

虽然这似乎适用于我的计算机,但我担心它可能不适用于其他计算机,或者文件格式最终可能会因计算机而异(例如,32 位计算机与 64 位计算机)。 难道我做错了什么?我应该如何实现我的代码以使用每个数字的恒定字节数?

我应该只使用 fread(这也可能使我的代码更快)吗?

最佳答案

使用 stdint.h 中的类型来确保输入和输出的字节数相同。

然后你只剩下处理字节序问题,你的代码可能不会 真正处理。

使用别名 char* 序列化 long 会使您在写入的文件中为具有不同字节顺序的平台留下不同的字节顺序。

你应该像这样分解字节:

char c1 = (val >>  0) & 0xff;
char c2 = (val >>  8) & 0xff;
char c3 = (val >> 16) & 0xff;
char c4 = (val >> 24) & 0xff;

然后使用类似的东西重新组合:

val = (c4 << 24) |
      (c3 << 16) |
      (c2 <<  8) |
      (c1 <<  0);

关于c - 在 C 代码中写入和读取 long int 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1105938/

相关文章:

c++ - 使用 for 、if 和 else 的正确 openmp 实现

java - 从给定的类路径获取文件

c# - SQL Server - Guid VS。长

c - SDL Audio - 只播放静态噪音

c - 如何处理跨平台 C 库中的 Unicode 路径?

python - 如何在 Python3 中使用 StringIO?

java - 我可以在文本文件中使用 Scanner 类来获取信息吗?

C - 递归调用遍历子目录并打印所有文件+大小(使用 stat)

objective-c - Objective C - 如何将 double 转换为 long

c - 如何在堆栈上分配具有灵活数组成员的结构