STL的string很強大,用起來也感覺很舒服,這段時間在代碼中涉及到了用string存取二進制數據的問題,這里記錄一下,以供以后參考。
首先提一下STL中string的參考資料:http://www.cplusplus.com/reference/string/string/ ,不懂的朋友可以看下。
在數據傳輸中,二進制數據的buffer一般用系統預設的大數組進行存儲,而不是STL的string等,比如:
const int max_length = 1024 * 1024;
unsigned char data[max_length];
因為二進制數據中可能會包含0x00(即:'\0'),剛好是字符串結束標志……
如果我們的代碼是如下寫的:
char data[max_length];
size_t length = sockClient.read_some(boost::asio::buffer(data), ec);
string strData(data);
我只能說,這個處理字符串應該沒問題,如果是二進制的話,會被string的構造函數給截斷一部分,導致strData和data的數據不一致。
其實一個簡單的demo就可以說明問題,比如如下代碼:
#include <string>
#include <iostream>
using namespace std;
int main()
{
char data[] = {'A','b',0x00,'c','d'};
string str1(data),str2(data,sizeof(data));
cout<<str1<<endl;
cout<<str1.size()<<endl;
cout<<str2<<endl;
cout<<str2.size()<<endl;
return 0;
}
運行效果:
Ab
2
Abcd
5
從運行結果不難發現,采用str2的那種方式就可以保證string中的數據和原始data中的數據一致。這是因為采用不同的構造函數不同,導致結構完全不一樣,這個可以從我前面給出的網址中去查看具體的構造函數說明加以理解。
這里我們回到前面的那個問題,如果想保存二進制的話,我們應該如下操作:
char data[max_length];
size_t length = sockClient.read_some(boost::asio::buffer(data), ec);
string strData(data,length);
如果要取出數據的話,也簡單(這個還以socket數據收發為例):
......
// deal with strData
......
boost::asio::write(sockClient, boost::asio::buffer(strData.c_str(),strData.length()));
這里的strData.c_str()即為數據,strData.length()即為要發送的數據長度(當然也可以使用strData.size()來操作)。
當然,我這里用string來存取二進制數據,也只是為了操作方便,感覺這個不是太好,應該會有很多朋友不提倡這種做法的,這里提供一個思路,大家覺得好就采用,覺得不好就一笑了之,呵呵……
好,就這些了,希望對你有幫助。
E-Mail : Mike_Zhang@live.com