交换无符号短整数

时间:2018-03-29 14:01:03

标签: c bit-manipulation byte endianness

我有一个部分工作的功能,涉及写入文件。

我有一个类型arr的数组unsigned short int,每个元素都必须以二进制格式写入文件。

我的初始解决方案是:

for(i = 0; i < ROWS; i++) {
    fwrite(&arr[i], 1, sizeof(unsigned short int), source);
}

上面的代码在将unsigned short ints写入文件时起作用。此外,source是指向以二进制格式写入的文件的指针。但是,我需要交换字节,并且我很难这样做。从本质上讲,作为abcd写入文件的内容应为cdab

我的尝试:

unsigned short int toWrite;
unsigned short int swapped;
for(i = 0; i < ROWS; i++) {
    toWrite = &arr[i];
    swapped = (toWrite >> 8) | (toWrite << 8);

    fwrite(swapped, 1, sizeof(unsigned short int), source);
}

但是我得到了一个分段错误核心转储。我阅读并使用了对这个问题的赞成回答 - convert big endian to little endian in C [without using provided func] - 但它似乎没有起作用。有什么建议?谢谢!

2 个答案:

答案 0 :(得分:3)

你的尝试是非常错误的(你复制的答案是可以的,问题不在于交换本身)

首先,您要将值的地址交换,然后传递而不是要写入的地址。它应该是:

unsigned short int toWrite;
unsigned short int swapped;
for(i = 0; i < ROWS; i++){
        toWrite = arr[i];
        swapped = (toWrite >>8) | (toWrite <<8); // that part is OK
        fwrite(&swapped, 1 , sizeof(unsigned short int) , source);  
}

我很肯定编译器警告你这个。警告很有用。

答案 1 :(得分:3)

欢迎来到非便携式二进制格式的世界。

交换数字是一个容易出错的黑客,因为它使程序不可移植:是否交换值取决于编译和运行程序的系统的字节顺序。您的程序有一个非常简单的错误:您传递swapped的值而不是其地址。您可以使用以下方法修复它:

fwrite(&swapped, sizeof(swapped), 1, source);

然而,对您的问题更好的解决方案是在程序中明确处理字节序。这是一个以大端顺序编写数字的便携式解决方案:

/* writing 16 bit unsigned integers in big endian order */
for (i = 0; i < ROWS; i++) {
    putc(arr[i] >> 8, source);
    putc(arr[i] & 255, source);
}

如果您希望以小端顺序编写,则这是替代版本:

/* writing 16 bit unsigned integers in little endian order */
for (i = 0; i < ROWS; i++) {
    putc(arr[i] & 255, source);
    putc(arr[i] >> 8, source);
}

请注意,为输出文件source命名流变量有点令人困惑。