工作的時候遇到一個問題,需要把一個存儲二進制網絡流的buff轉化爲一個字符串進行存儲。在網上搜了半天看到的方法都比較複雜。
在這裏介紹一種自己認爲比較簡便的方法。
二進制網絡流一般都是unsigned char類型。跟char的區別在於讀取的方式不同,但是存儲
的位數並沒有什麼不同。假設unsigned char Buff[] 裏存儲了二進制的網絡流,在這裏我們可以先使用char *NewBuff = (char*)Buff進行強制轉換。
接下來就是由字符串轉化爲string就可以了。但是有個問題,在生成string的時候,string會複製buff中的字符直到遇到\0 的字符。
大家可以來看看構造一個string的代碼實現:
- inline String::String(const char* str)
- {
- if(!str)m_data=0; //聲明爲inline函數,則該函數在程序中被執行時是語句直接替換,而不是被調用
- else {
- m_data=new char[strlen(str)+1];
- strcpy(m_data,str);
- }
- }
傳入的buf會由strlen來計算長度,我們再來看看strlen的實現:
int strlen(const char *str)
{
assert(str != NULL);
int len = 0;
while((*str++) != '\0')
len++;
return len;
}
大家可以看到,strlen遇到\0 就認爲字符已經到結尾了。假設我們的Buff 存儲的網絡流裏頭包含\0,那麼NewBuff被strlen
計算長度的時候,遇到\0就停止了。導致Buff在\0後面的字符都沒有計算在內,最後生成的字符串就是\0前面的部分,這就造成了
信息丟失。在這裏我們需要在處理網絡收包的時候通過某些方法知道我們這個buff的長度,然後調用string::assign(char*,size_t n)
指定buff拷貝的長度,這樣子buff中的內容都會被拷貝到string裏頭。不會造成數據的丟失。將string取出來再進行逆向的
轉換就可以了。大家可以驗證下。