3

我正在尝试使用 fstream 读取 bmp 文件。但是,它会跳过 08 和 0E(十六进制)之间的值,例如,对于值 42 4d 8a 16 0b 00 00 00 00 00 36

它读到

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);不接受无符号字符。有人有用无符号字符写的功能吗?

4

7 回答 7

7

如果您想一次读取一个字节的文件,这是 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 回答