2015-02-07 64 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