2011-04-22 61 views
3

所以我正在做一個字符串轉換爲無符號長的使用strtoul在小端和大端機器上。小端機返回正確的值,而大端機不返回正確的值。這個功能在大端機上真的不兼容嗎?如果是這樣,是否有解決方法?strtoul不endian安全嗎?

代碼:

printf ("%s\n",cLongs); 
theLongs[i] = strtoul(cLongs, NULL, 10); 
cout << "returned unsigned long value from string: " << theLongs[i] << endl; 

小尾數結果:

1099188638048931 
returned unsigned long value from string: 1099188638048931 

大端結果:

1099188638048931 
returned unsigned long value from string: 4294967295 

附:看起來總是爲Big Endian示例返回相同的數字。

回答

4

strtoul返回上溢ULONG_MAX。這就是你打的。我假設一個在32位上運行,另一個在64位上運行Endianess差異。 4294967295 == 0xFFFFFFFF,其對於32位機器將是ULONG_MAX


請試試以下兩種系統是否適用於您。目前爲止,我只能在64位Little Endian Linux上進行測試。如果是這樣,你可以使用字符串流轉換(這是無論如何C++風格做的事情):

#include <iostream> 
#include <sstream> 

int main() 
{ 
    using namespace std; 
    string sval("1099188638048931"); // your huge value, exceeding 32bit 
    istringstream sst(sval); // assign string to a stream 
    unsigned long long myval; 
    sst >> myval; // convert stream to unsigned 64bit integer 
    cout << myval << endl; // output the converted result 
    return 0; 
} 

注意,這unsigned long long將不得不unsigned __int64與MSVC。其他編譯器可能有其他名稱。如果你是幸運的,你將在所有平臺上有standard types,並且可以使用uint64_t ...

+0

這似乎是在嘗試更小的unsigned int後的正確答案。有沒有解決這個問題的方法,或者我是否陷入了困境和困境之中? – 2011-04-22 03:33:11

+0

@Jeff:我很確定沒有可以跨平臺工作的解決方案,因爲這將超出C標準。但是可以使用C++字符串流和'<<'運算符來獲取更大的整數值,而不是C運行時。我很確定C++應該爲此做好準備。我會看看我能不能給你一個小例子一起入侵。也會給出C++是否準備好的答案:) – 0xC0000022L 2011-04-22 03:36:46

+0

@Jeff:看你的系統是否有'strtoull'(BSD上的'strtouq'),它使用'unsigned long long' - 可能都是64位。 – 2011-04-22 03:37:14