将 char[] 转换为 off_t
Convert char[] to off_t
我在二进制文件中存储了一个文件大小,我能够将这个文件大小放入 char[8]
缓冲区。我想将此 char[]
转换为 off_t
类型,以便能够将其作为 truncate(const char *path, off_t length)
.
的参数传递
我尝试了这种天真的方法,它似乎大部分时间都有效,但有时会失败,并给我一个奇怪的位序列。
off_t pchar_2_off_t(char* str, size_t size)
{
off_t ret = 0;
size_t i;
for (i = 0; i < size; ++i)
{
ret <<= 8;
ret |= str[i];
}
return ret;
}
假设包含文件大小的文件是在完全相同的机器上创建的,并且它最初是用 off_t
类型编写的,您可以只转换 char[]
-> off_t
.例如:
off_t filesize = *((off_t*)str);
只需批量复制有问题的数据:
#include <string.h> /* for memcpy() */
...
char str[8];
/* Read 8 bytes binary data into str here. */
off_t off_file;
memcpy(&off_file, str, sizeof off_file);
要解决任何终端问题,只需执行以下操作:
off_t off = ntohll(off_file); /* Assuming ntohll being the 64bit version of ntohl(). */
由于 ntohll()
是非标准的,请在此处查看一些可能的实现方法:64 bit ntohl() in C++?
unsigned const char blah[8] = {0xdd,0xee,0xaa,0xdd,0xbb,0xee,0xee,0xff};
off_t * scalar = (off_t *) malloc(8);
memcpy(scalar, blah, 8);
printf("%llx\n",*scalar);
输出(在我的英特尔机器上):ffeeeebbddaaeedd
什么什么?!你说....这种方法有问题,它不可移植...这是 endianness 的问题...
因此,如果您想以可移植的方式执行此操作,您实际上需要了解字节顺序和特殊情况,或者只是通过循环进行转换:
*scalar = 0;
for (int i = 0; i < 8; i++)
{
*scalar += (uint64_t)blah[i] << ( 8 * (7-i));
}
printf("%llx\n",*scalar);
输出(在所有具有 64 位 off_t 的机器上):ddeeaaddbbeeeeff
ret |= str[i];
是一个问题,因为 str[i]
可能会在转换为 int
时进行符号扩展,在 ret
中设置许多位。由 @pmg and commented by @mafso
暗示
off_t pchar_2_off_t(const char* str, size_t size) {
off_t ret = 0;
size_t i;
for (i = 0; i < size; ++i) {
ret <<= 8;
ret |= (unsigned char) str[i];
}
return ret;
}
我在二进制文件中存储了一个文件大小,我能够将这个文件大小放入 char[8]
缓冲区。我想将此 char[]
转换为 off_t
类型,以便能够将其作为 truncate(const char *path, off_t length)
.
我尝试了这种天真的方法,它似乎大部分时间都有效,但有时会失败,并给我一个奇怪的位序列。
off_t pchar_2_off_t(char* str, size_t size)
{
off_t ret = 0;
size_t i;
for (i = 0; i < size; ++i)
{
ret <<= 8;
ret |= str[i];
}
return ret;
}
假设包含文件大小的文件是在完全相同的机器上创建的,并且它最初是用 off_t
类型编写的,您可以只转换 char[]
-> off_t
.例如:
off_t filesize = *((off_t*)str);
只需批量复制有问题的数据:
#include <string.h> /* for memcpy() */
...
char str[8];
/* Read 8 bytes binary data into str here. */
off_t off_file;
memcpy(&off_file, str, sizeof off_file);
要解决任何终端问题,只需执行以下操作:
off_t off = ntohll(off_file); /* Assuming ntohll being the 64bit version of ntohl(). */
由于 ntohll()
是非标准的,请在此处查看一些可能的实现方法:64 bit ntohl() in C++?
unsigned const char blah[8] = {0xdd,0xee,0xaa,0xdd,0xbb,0xee,0xee,0xff};
off_t * scalar = (off_t *) malloc(8);
memcpy(scalar, blah, 8);
printf("%llx\n",*scalar);
输出(在我的英特尔机器上):ffeeeebbddaaeedd
什么什么?!你说....这种方法有问题,它不可移植...这是 endianness 的问题...
因此,如果您想以可移植的方式执行此操作,您实际上需要了解字节顺序和特殊情况,或者只是通过循环进行转换:
*scalar = 0;
for (int i = 0; i < 8; i++)
{
*scalar += (uint64_t)blah[i] << ( 8 * (7-i));
}
printf("%llx\n",*scalar);
输出(在所有具有 64 位 off_t 的机器上):ddeeaaddbbeeeeff
ret |= str[i];
是一个问题,因为 str[i]
可能会在转换为 int
时进行符号扩展,在 ret
中设置许多位。由 @pmg and commented by @mafso
off_t pchar_2_off_t(const char* str, size_t size) {
off_t ret = 0;
size_t i;
for (i = 0; i < size; ++i) {
ret <<= 8;
ret |= (unsigned char) str[i];
}
return ret;
}