[英]C++ reading binary files
我想了解讀取二進制文件如何在C ++中工作。 我的代碼:
int main() {
ifstream ifd("input.png",ios::binary |ios::ate);
int size = ifd.tellg();
ifd.seekg(0, ios::beg);
vector<char> buffer;
buffer.reserve(size);
ifd.read(buffer.data(), size);
cout << buffer.data();
return 0;
}
我認為,如果我輸入我的緩沖區,我會得到二進制的結果,但事實並非如此。
My output is: ˙Ř˙á6Exif
如果我讀取文本文件,它將以正常形式顯示文本而不是二進制文本。 顯然我的邏輯不正確。 如何將文件讀取到緩沖區以使其包含二進制值? Ps我這樣做是為了實現Shannon-Fano算法,所以如果有人對閱讀二進制文件有任何建議,我將不勝感激。
您需要調整矢量大小,而不是保留它:
int main()
{
ifstream ifd("input.png", ios::binary | ios::ate);
int size = ifd.tellg();
ifd.seekg(0, ios::beg);
vector<char> buffer;
buffer.resize(size); // << resize not reserve
ifd.read(buffer.data(), size);
cout.write(buffer.data(), buffer.size()); // you cannot just output buffer to cout as the buffer won't have '\0' ond-of-string terminator
}
否則,您的代碼會嘗試將size
字符讀入空緩沖區。 您也可以使用設置矢量大小的向量構造函數: vector<char> buffer(size);
您可以這樣輸出緩沖區的字節值:
void dumpbytes(const vector<char>& v)
{
for (int i=0; i<v.size(); ++i)
{
printf("%u ", (unsigned char)v[i]);
if ((i+1) % 16 == 0)
printf("\n");
}
printf("\n");
}
或者像常見的十六進制編輯器那樣用於十六進制輸出:
void dumphex(const vector<char>& v)
{
const int N = 16;
const char hex[] = "0123456789ABCDEF";
char buf[N*4+5+2];
for (int i = 0; i < v.size(); ++i)
{
int n = i % N;
if (n == 0)
{
if (i)
puts(buf);
memset(buf, 0x20, sizeof(buf));
buf[sizeof(buf) - 2] = '\n';
buf[sizeof(buf) - 1] = '\0';
}
unsigned char c = (unsigned char)v[i];
buf[n*3+0] = hex[c / 16];
buf[n*3+1] = hex[c % 16];
buf[3*N+5+n] = (c>=' ' && c<='~') ? c : '.';
}
puts(buf);
}
緩沖區“Hello World!” 數據印刷如下:
48 65 6C 6C 6F 20 57 6F 72 6C 64 21 Hello World!
以二進制模式打開文件意味着您的操作系統不會透明地轉換CR / LF / CRLF格式之間的行結尾。
它對你的計算機如何打印一個字符串沒有任何影響,七行之后。 我不知道“得到二進制結果”是什么意思,但我建議通過以十六進制對表示方式一次打印一個組成字節來渲染vector<char>
的內容:
std::cout << std::hex << std::setfill('0');
for (const auto byte : buffer)
std::setw(2) << byte;
輸出看起來像:
0123456789abcdef0123456789abcdef
每兩個字符代表數據中一個字節的0-255字節值,使用base-16(或“hex”)數字系統。 這是非文本信息的常見表示。
或者, 您可以輸出base-2中的數據 (字面意思是“二進制”)。
由您決定如何呈現信息。 文件打開模式與矢量無關。
你還需要修復矢量的大小; 在你打電話的那一刻。 .reserve
你的意思.resize
。
基於Pavel回答,你也可以添加它來查看真實二進制數據,即0
和1
秒。 不要忘記包含bitset標頭。
void dumpbin(const vector<char>& v)
{
for (int i = 0; i < v.size(); ++i)
{
cout <<bitset<8>((unsigned char)(v[i])) << " ";
if ((i + 1) % 8 == 0)
printf("\n");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.