3

fstream を使用して bmp ファイルを読み込もうとしています。ただし、たとえば、値 42 4d 8a 16 0b 00 00 00 00 00 36 の場合、08 と 0E (16 進数) の間の値はスキップされます。

それは読む

42 4d 8a 16 00 00 00 00 00 36

ドキュメントに存在しないように 0b をスキップします。

何をすべきか?

コード:

ifstream in;
in.open("ben.bmp", ios::binary);
unsigned char a='\0';
ofstream f("s.txt");
while(!in.eof())
{
    in>>a;
    f<<a;
}

編集:in.read(a,1);代わりに使用in>>a;すると読み取りの問題が解決しますが、符号なし文字を書き込む必要があり、符号なし文字をf.write(a,1);受け入れません。unsigned chars で書き込みを行う機能を持っている人はいますか?

4

7 に答える 7

7

一度に 1 バイトずつファイルを読み取りたい場合、これは istream バッファ イテレータを使用するのに適しています。

int main()
{
   ifstream in("ben.bmp", ios::binary);  
   ofstream f("s.txt");  

   //
   // Note: this is NOT istream_iterator
   // The major different is that the istreambuf_iterator does not skip white space.
   //
   std::istreambuf_iterator<char>  loop(in);
   std::istreambuf_iterator<char>  end;

   for(; loop != end; ++loop)
   {
       f << (*loop);  
   }

   // You could now also use it with any of the std algorithms
       // Alternative to Copy input to output
            std::copy(loop,end,std::ostream_iterator<char>(f));

       // Alternative if you want to do some processing on each element
       // The HighGain_FrequencyIvertModulator is a functor that will manipulate each char.
            std::transform( loop,
                            end,
                            std::ostream_iterator<char>(f),
                            HighGain_FrequencyIvertModulator()
                          );
}  
于 2010-01-08T22:09:30.853 に答える
6

いくつかの問題:

while(!in.eof())
{
    in>>a;
    f<<a;
}

ファイルを読み取る正しい方法ではありません。読み取りが機能したかどうかを確認する必要があります。

while( in >> a)
{
    f<<a;
}

次に、バイナリ モードでファイルを読み取りたい場合は、 read() および関連する関数を使用する必要があります。 >> 演算子は、ファイルが開かれているモードに関係なく、常にフォーマットされた (非バイナリ) 入力を実行します。

編集:書き込みにはキャストが必要です:

unsigned char c = 42;
out.write( (char *) & c, 1 );
于 2010-01-08T21:58:13.403 に答える
6

operator>>とはoperator<<、テキストの入力と出力用に設計されています。

バイナリ ファイルの場合はread()、 とwrite().

于 2010-01-08T21:59:13.057 に答える
4

これは、ストリームがバイトを ASCII 文字として解釈しているためです。08 から 0e は空白 (水平タブ、改行、垂直タブ、キャリッジ リターンなど) であり、スキップされます。他の回答が言ったように、ストリームの read() メソッドを使用する必要があります。

于 2010-01-08T22:02:28.963 に答える
2
#include <fstream>
#include <iostream>
#include <string>

int main(int argc, char *argv[])
{
  const char *bitmap;
  const char *output = "s.txt";

  if (argc < 2)
    bitmap = "ben.bmp";
  else
    bitmap = argv[1];

  std::ifstream  in(bitmap, std::ios::in  | std::ios::binary);
  std::ofstream out(output, std::ios::out | std::ios::binary);
  char a;

  while (in.read(&a, 1) && out.write(&a, 1))
    ;

  if (!in.eof() && in.fail())
    std::cerr << "Error reading from " << bitmap << std::endl;

  if (!out)
    std::cerr << "Error writing to "   << output << std::endl;

  return 0;
}
于 2010-01-08T22:07:55.877 に答える
1

バイナリ データを扱う場合は、オーバーロードされたビット単位の演算子 (<< および >>) ではなく、read() を使用します。

ストリームを使用する必要がある場合は、次のようにすることができます。

std::ifstream ifs("bar", std::ios::in | std::ios::binary);
std::ofstream ofs("foo", std::ios::out | std::ios::binary);
ofs << ifs.rdbuf();
于 2010-01-08T21:56:49.673 に答える
0

次のようにバイナリファイルとして開いていることを確認してください。

ifstream ifs('input.bin', ios::in | ios::binary);

ofstream ofs('output.bin', ios::out | ios::binary);

また、ifs.good()開いたファイルに問題がないことを確認することもお勧めします。

于 2010-01-08T21:54:40.007 に答える