用于读取二进制文件的变量的问题

时间:2012-05-09 06:10:42

标签: c++ binaryfiles

我正在编写一些串口代码,需要将文件内容(二进制)读取到变量中。 从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个字符。

2 个答案:

答案 0 :(得分:1)

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

有关帮助引脚输出二进制数据,请参阅此内容: How to make cout behave as in binary mode?

答案 1 :(得分:0)

嗯。快速浏览一下您引用的页面会显示作者没有 了解C ++中的IO。避免它,因为它说的很多 错。

其余部分:.jpg不是文本格式,不能简单输出 到cout。当您使用<<时,输出会在第一个时停止 '\0'字符,但各种二进制数据可能会导致奇怪的影响: 数据可以解释为重新定位光标的转义序列, 锁定键盘(实际上发生在我身上),等等 即使您使用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>,所以您没有 担心释放记忆。)