【问题标题】:Issues with variable used in reading binary file读取二进制文件时使用的变量问题
【发布时间】:2012-05-09 06:10:41
【问题描述】:

我正在编写一些串行端口代码,需要将文件的内容(二进制)读取到变量中。 从http://www.cplusplus.com/doc/tutorial/files/ 的“二进制文件”示例开始, 我尝试打开一个 .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 个字符。

【问题讨论】:

    标签: c++ binaryfiles


    【解决方案1】:

    您的二进制数据中可能有一个 0。 cout 是一个文本流,因此将 memblock 视为一个字符串。如果它到达一个空字符,那么它认为字符串已经完成。

    有关输出二进制数据的一些帮助引脚,请参见此处: How to make cout behave as in binary mode?

    【讨论】:

      【解决方案2】:

      嗯。快速浏览您引用的页面表明作者没有 对 C++ 中的 IO 了解很多。避免它,因为它所说的大部分内容是 错了。

      剩下的:.jpg不是文本格式,不能简单输出 到cout。当你使用&lt;&lt;时,当然输出会停在第一个 '\0' 字符,但各种二进制数据可能会导致奇怪的效果: data 可以解释为重新定位光标的转义序列, 锁定键盘(实际上发生在我身上一次)等这些 即使您使用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&lt;char&gt;,所以你没有 担心释放内存。)

      【讨论】:

        猜你喜欢
        • 2011-03-30
        • 2011-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多