2011-07-04 39 views
1

我正在用C++編寫一個程序來偵聽來自另一個程序的tcp消息流,以便從網絡攝像頭提供跟蹤數據。我有套接字連接,我得到的所有信息,但很難分裂成我想要的數據。將字符數組轉換爲一個整數和浮點數序列

這裏的數據的格式在未來:

8字節的報頭: 4字符串, 整數

32字節的消息: 整數, 浮子, 浮子, 浮子, 浮, float

這是所有被卡在名爲緩衝區的char數組中。我需要能夠將不同的字節解析爲我需要的基元。我試圖製作更小的子數組,比如headerString,它是通過循環遍歷並複製緩衝區數組的前4個元素來填充的,並且我得到了正確的打印輸出('CCV')。但是,當我嘗試與下一個元素(獲取整數)相同的事情,並嘗試打印出來,我得到奇怪的ascii字符被打印出來。我已經嘗試使用stdlib.h中的atoi方法將headerInt數組轉換爲整數,但它總是打印出零。

我已經在python中使用優秀的解壓方法完成了這個任務,它們是C++中的任何替代方案嗎?

任何幫助非常感謝,

喬丹

鏈接

CCV packet structure

Python unpack method

+1

endianness?網絡秩序? – sehe

+0

這裏給出的信息不足。整數/浮點數有多大。他們存儲什麼endianess? **你如何使用unpack()這裏有我們可以使用的信息來解決上面的一些問題。 –

+0

它看起來不是一個「字符數組」,它看起來是二進制數據 - 例如一個* integer *是四個字節,所以你打印的是每個字節的十六進制值(轉換爲[非]可打印字符)。你需要了解積分值是如何序列化(和浮點數),然後寫出相反的... – Nim

回答

4

緩衝區只包含您通過 網絡讀取的原始圖像。您必須將緩衝區中的字節轉換爲您想要的任何格式 。該字符串是容易的:

std::string s(buffer + sOffset, 4); 

(假設,當然,該內部字符編碼相同 作爲文件—大概ASCII的延伸在)

其他是比較複雜,並取決於 外部數據的格式。從頭文件的描述中,我收集到的整數是四個字節,但仍然沒有告訴我任何有關其表示的內容。根據不同的情況下,無論是:

int getInt(unsigned char* buffer, int offset) 
{ 
    return (buffer[offset ] << 24) 
     | (buffer[offset + 1] << 16) 
     | (buffer[offset + 2] << 8) 
     | (buffer[offset + 3]  ); 
} 

int getInt(unsigned char* buffer, int offset) 
{ 
    return (buffer[offset + 3] << 24) 
     | (buffer[offset + 2] << 16) 
     | (buffer[offset + 1] << 8) 
     | (buffer[offset ]  ); 
} 

可能會做的伎倆。( 整數的其他四字節表示是可能的,但它們是非常罕見的。類似地,將無符號結果的變換和or轉換爲int 的轉換是實現定義的,但實際上,上述將幾乎在所有地方都工作 。)

你給有關浮體的表示是在 消息格式的唯一暗示:32個字節,減去一個4字節的整數,離開 5浮筒28個字節;但28沒有進入五,所以我甚至不能猜測浮點數的長度(除了必須在某處填充 )。但是如果外部格式與內部格式 不完全相同,則轉換浮點數可能會更多或更少。

+1

對不起,我得到的數字是錯誤的,主要消息是24個字節長,-4給每個浮點4個字節。謝謝你的回答! – jordanwise

+1

這留下了浮點格式的問題。 *如果*所有目標平臺都使用IEEE(忘記大型機),並且* if *格式使用IEEE,* if *您的編譯器允許有趣的別名('-fno-strict-aliasing' with g ++)比「正確」更容易)將值作爲int讀取,然後將結果的地址reinterpret_cast重新讀入float *。否則,你必須玩弄個別位,'ldexp()'等。 –

-1

像這樣的東西可能工作:

struct { 
    char string[4]; 
    int integers[2]; 
    float floats[5]; 
} Header; 

Header* header = (Header*)buffer; 

您應該檢查sizeof(Header) == 32

+0

-1:這樣的事情幾乎肯定不會奏效,除非偶然。 –