0

シリアル ポート コードを書いていて、ファイルの内容 (バイナリ) を変数に読み込む必要があります。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 ビット) だけです。

ただし、特に奇妙なのは、問題があると思われる変数「memblock」で ostream::write() を使用すると、完全に機能することです。

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

つまり、新しい .jpg ファイルを作成します。

私の質問は、memblock 変数に最初の 4 文字しか含まれていないように見える理由です。

4

2 に答える 2

1

バイナリ データに 0 が含まれている可能性があります。coutはテキスト ストリームなのでmemblock、文字列として見えます。null 文字に達すると、文字列が終了したと見なされます。

バイナリ データを出力するピンのヘルプについては、これを参照してください: cout をバイナリ モードのように動作させるには?

于 2012-05-09T06:14:33.650 に答える
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>ため、メモリの解放について心配する必要はありません。)

于 2012-05-09T08:17:04.003 に答える