【问题标题】:fstream skipping characters without reading in bitmapfstream跳过字符而不读取位图中
【发布时间】:2010-01-08 21:51:18
【问题描述】:

我正在尝试使用 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&gt;&gt;a; 可以解决阅读问题,但我需要编写无符号字符,而f.write(a,1); 不接受无符号字符。有人有用无符号字符写的功能吗?

【问题讨论】:

  • 贴一些说明问题的代码。
  • >> 运算符跳过空格。
  • 您似乎正在尝试将文件读取为“十六进制”值。不要忘记在使用流之前插入 hex 操纵器。

标签: c++ bitmap fstream


【解决方案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()
                          );
}  

【讨论】:

    【解决方案2】:

    operator&gt;&gt;operator&lt;&lt; 专为文本输入和输出而设计。

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

    【讨论】:

      【解决方案3】:

      几个问题:

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

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

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

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

      编辑:写需要演员:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:
          #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;
          }
          

          【讨论】:

          • 知道了。我们没有在 read() 中使用 &,这一定是导致问题的原因。再次感谢!
          • 虽然这个答案很好,但如果您使用 Martin 概述的迭代器和算法,它可能会更容易阅读和编写。
          【解决方案6】:

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

          如果你需要使用流,可以这样做:

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

          【讨论】:

            【解决方案7】:

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

            ifstream ifs('input.bin', ios::in | ios::binary);
            
            ofstream ofs('output.bin', ios::out | ios::binary);
            

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

            【讨论】:

            • 不,没有影响。
            猜你喜欢
            • 2012-02-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-01
            相关资源
            最近更新 更多