2012-05-09 77 views
0

我正在編寫一些串行端口代碼,需要將文件的內容(二進制)讀取到變量中。 從「二進制文件」的例子在http://www.cplusplus.com/doc/tutorial/files/, 起始I嘗試打開.jpg文件:用於讀取二進制文件的變量的問題

#include <iostream> 
#include <fstream> 
using namespace std; 

ifstream::pos_type size; 
char * memblock; 

int main() { 
    ifstream file ("example.jpg", ios::in|ios::binary|ios::ate); 
    if (file.is_open()) 
    { 
    size = file.tellg(); 
    memblock = new char [size]; 
    file.seekg (0, ios::beg); 
    file.read (memblock, size); 
    file.close(); 

    cout << memblock << endl; 

    delete[] memblock; 
    } 
else cout << "Unable to open file"; 
return 0; 
} 

然而,僅前4個字符(32位)被印刷在控制檯中。

什麼特別奇怪的是,雖然使用的ostream :: write()方法與假想故障變量「memblock」完美的作品:

ofstream fileOut ("writtenFile.jpg",ios::out|ios::binary); 
fileOut.write(memblock,size); 
fileOut.close(); 

即它會創建一個新的.jpg文件。

所以我的問題是爲什麼memblock變量似乎只包含前4個字符。

回答

1

您的二進制數據中可能有一個0。 cout是一個文本流,因此看起來在memblock作爲一個字符串。如果它達到空字符,則認爲該字符串已完成。

一些幫助引腳輸出二進制數據顯示方式: How to make cout behave as in binary mode?

0

嗯。快速瀏覽一下你所引用的頁面,可以看出作者對C++中的IO瞭解不多。避免它,因爲它說的很多是 錯誤。

其餘:.jpg不是一個文本格式,不能簡單地輸出 到cout。當您使用<<時,當然,輸出停止在第一個字符處,但各種二進制數據可能會導致更奇怪的效果: 數據可能會被解釋爲重定位光標的轉義序列, 鎖定鍵盤(實際上發生在我曾經)等等。即使您使用std::cout.write()(這不會在'\0'字符處停止 字符),也會發生這些 問題。如果你想要可視化數據, 你最好的選擇是某種二進制轉儲。 (我使用類似 以下用於可視化數據的大塊:

template <typename InputIterator> 
void 
process(
    InputIterator  begin, 
    InputIterator  end, 
    std::ostream&  output = std::cout) 
{ 
    IOSave    saveAndRestore(output) ; 
    output.setf(std::ios::hex, std::ios::basefield) ; 
    output.setf(std::ios::uppercase) ; 
    output.fill('0') ; 
    static int const lineLength(16) ; 
    while (begin != end) { 
     int     inLineCount = 0; 
     unsigned char  buffer[ lineLength ] ; 
     while (inLineCount != lineLength && begin != end) { 
      buffer[inLineCount] = *begin; 
      ++ begin; 
      ++ inLineCount; 
     } 
     for (int i = 0 ; i < lineLength ; ++ i) { 
      static char const *const 
           separTbl [] = 
      { 
       " ", " ", " ", " ", 
       " ", " ", " ", " ", 
       " ", " ", " ", " ", 
       " ", " ", " ", " ", 
      } ; 
      output << separTbl[ i ] ; 
      if (i < inLineCount) { 
       output << std::setw(2) 
         << static_cast< unsigned int >(buffer[ i ] & 0xFF)) ; 
      } else { 
       output << " " ; 
      } 
     } 
     output << " |" ; 
     for (int i = 0 ; i != inLineCount ; ++ i) { 
      output << (i < lengthRead && isprint(buffer[ i ]) 
         ? static_cast<char>(buffer[ i ]) 
         : ' ') ; 
     } 
     output << '|' << std::endl ; 
    } 
} 

(你還需要讀入std::vector<char>,所以你不必 擔心釋放內存)