一個標準的c++程式。
先來一段 bin與hexview互轉的函數。
hexviewtoBin:
下面這段程式用來把一個文本表示的十六進位數轉換為二進位的形式:
/*
* 函數作用:把長為len的字串按s每step個byte中包含一個byte的格式轉為二進位的形式。
*範晨鵬
*@param sDesBuffer 存放結果的緩衝
*@param sSourcBuffer 源字串
*@param len 源字串的長度
*@param step 每個十六進位表示符所佔的位元組數
*注意:本函數沒有考慮表示十六進位數的字元中有小寫字母的情況。
*/
void HexToBin(char* sDesBuffer, const char* sSourcBuffer, unsigned int len, unsigned step)
{
const char dic[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16};
char* pSourcBuffer = (char*) sSourcBuffer;
char* pDesBuffer = sDesBuffer;
for (int i = 0; i < len; i+=step)
{
*pDesBuffer++ = char(dic[*pSourcBuffer - 0x30] * 16 + dic[*(pSourcBuffer+1) - 0x30]);
pSourcBuffer += step;
}
return;
}
binto hexview
/************************************************************************
* 把 bubfin所指向的記憶體資料以十六進位視圖發送到寫到 strout 中
* by fancp 2009-09-08
*
**************************************************************************/
char* GetHexView( char* strout, size_t strLen, const char *bufIn, size_t bufLen )
{
int offset = 0;
strout[0] = '\0';
if( 3 * bufLen > strLen )
{
return strout;
}
for( offset = 0; offset < bufLen; offset++)
{
sprintf( strout + 3*offset, "%02X " , (unsigned char)bufIn[offset] );
}
return strout;
}
下面的main函數將檔案中的字串讀入,並儲存成十六進位的形式。
# include <iostream>
using namespace std;
void main()
{
char sLineRead[LEN_LINE];
char sbin[200];
char pLineRead;
ifstream fin("test.txt");
ofstream fout("test.bin");
while(!fin.eof())
{
fin.getline(sLineRead, LEN_LINE);
HexToBin(sbin, sLineRead, fin.gcount(), 3);
fout.write(sbin, 20);
}
fin.close();
fout.close();
}
寫出來卻多了一個位元組。
如下:
文字檔 test.txt只有一行內容:A5 0A 02 00 00 3C 00 00 01 9E
寫為二進位檔案test.bin應該有十個byte。不想在vc++中卻為11個byte.其十六進位視圖如下:A5 0D 0A 02 00 00 3C 00 00 01 9E
在linux下編譯卻沒有此問題。苦苦思索幾個小時不得其解。這個 "0D"是從哪來的?
後在別人提醒下,意識到OD是分行符號。和0A組合在一起是windows下的斷行符號分行符號。
在windows下,如果以文字模式寫檔案,windows會將讀到的 "0D" 或 "0A" 寫為兩個字元 "0D 0A"。二進位模式卻不會這樣。
知道了癥結,便好下藥了。解決辦法是將test.bin以"ios::binary"的方式來開啟。
ofstream fout("test.bin", ios::binary);
哎!倒黴的windows。一個位元組花了我好幾個小時的時間~
附上轉大寫字母的函數:inline char Upper(char m)
{
return ( m <= 0x66 && m >= 0x61 ) ? m - 0x20 : m;
}