fstream在没有读取位图的情况下跳过字符

时间:2010-01-08 21:51:19

标签: c++ bitmap fstream

我正在尝试使用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);不接受无符号字符。有没有人用无符号字符进行写作?

7 个答案:

答案 0 :(得分: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()
                          );
}  

答案 1 :(得分:6)

几个问题:

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

不是读取文件的正确方法 - 您需要检查读取是否有效:

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

其次,如果要以二进制模式读取文件,则需要使用read()和相关函数 - &gt;&gt;无论打开文件的哪种模式,运算符都将始终执行格式化(非二进制)输入。

编辑:写入需要投射:

unsigned char c = 42;
out.write( (char *) & c, 1 );

答案 2 :(得分:6)

operator>>operator<<专为文本输入和输出而设计。

对于二进制文件,请使用read()write()

答案 3 :(得分:4)

这是因为流将字节解释为ascii字符。 08到0e是白色空格(水平制表符,换行符,垂直制表符,回车符等),它们被跳过。与其他答案一样,您需要使用流的read()方法。

答案 4 :(得分: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;
}

答案 5 :(得分:1)

处理二进制数据时,使用read()而不是重载的按位运算符(&lt;&lt;&gt;&gt;)

如果您需要使用流,可以执行以下操作:

std::ifstream ifs("bar", std::ios::in | std::ios::binary);
std::ofstream ofs("foo", std::ios::out | std::ios::binary);
ofs << ifs.rdbuf();

答案 6 :(得分:0)

确保将其打开为二进制文件,如下所示:

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

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

检查ifs.good()以确保您打开的文件一切正常

也是一种很好的做法