2015-02-07 118 views
2

我将文件大小存储在二进制文件中,我可以将此文件大小存储到char[8]缓冲区中。我想将此char[]转换为off_t类型,以便能够将它作为参数truncate(const char *path, off_t length)传递。将char []转换为off_t

我试过这种天真的方法,它似乎大部分时间工作,但它有时失败,给了我一个奇怪的位序列。

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; 
} 
+2

转换的'STR [1]'以某种签名:'RET | =(无符号)STR [1];' – pmg 2015-02-07 15:14:30

+1

你知道,如果你的编译器'char'类型是有符号还是无符号?这可能与它有关,可能是文件的实际*写入。 – 2015-02-07 15:14:38

+0

@pmg>它看起来没有任何作用。转换失败。 – user1527491 2015-02-07 15:19:09

回答

1

ret |= str[i];str[i]可以符号扩展问题在转换为int后,在中设置很多位10。通过@pmg隐含的评论说@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; 
} 
+2

注意:更迂回的解决方案将使用'ret << = CHAR_BIT;'因为'char'宽度并不总是8位。看到OP如何保存'str'会澄清细节。 – chux 2015-02-07 16:06:32

-1

假设包含完全相同的机器上创建文件大小的文件,它最初是一个off_t类型写的,你可以只投了char[] - >的off_t。例如:

off_t filesize = *((off_t*)str); 
+1

你可能是指'... = *((off_t *)str);'? – alk 2015-02-07 15:31:57

+0

我做了 - 谢谢 – user590028 2015-02-07 15:41:27

+0

如果你现在也可以相应地调整你的措辞,这将是一个有效的答案......你不是投到'off_t',而是'off_t *'。 – alk 2015-02-07 15:42:45

1

就有关批量复制数据:

#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); 

要解决任何endiness问题只是做:

off_t off = ntohll(off_file); /* Assuming ntohll being the 64bit version of ntohl(). */ 

由于ntohll()是非标准的,请看到一些可能的实现方法如下:64 bit ntohl() in C++?

+0

为什么它应该比cast(user59002答案)更好?输入时间较长,速度较慢。 – 2015-02-07 15:42:57

+0

@ user36740:我没有说它比任何东西更好或值得。 – alk 2015-02-07 15:45:41

+0

这有一个字节顺序问题。 – 2015-02-07 15:45:57

0
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

什么WHA?你说....这种方法有问题,它是它不是便携式...这是一个问题endianness ...

所以,如果你想做这个portably你需要其实无论是意识到字节序和特殊情况下,它的或只是一个循环转换:

*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

+0

这有一个对齐问题。 '标量'可能比'blah'更具限制性。 – chux 2015-02-07 15:47:57

+0

Minor:由于'off_t'的大小不一定与'unsigned long long'相同,所以使用'printf(“%llx \ n”,(unsigned long long)*标量);'是便携的。 'off_t'也被签名。 – chux 2015-02-07 16:00:25

+0

如果您不知道数据已存储在哪里,您有**没有** 100%的机会正确读取数据。 – alk 2015-02-07 16:00:59