【问题标题】:Why does calling istream::tellg() affect the behavior of my program?为什么调用 istream::tellg() 会影响我的程序的行为?
【发布时间】:2012-09-14 18:59:51
【问题描述】:

我正在尝试将 24 位位图图像转换为灰度。

#include<iostream>
#include<fstream>
#include<conio.h>
#include<stdio.h>
using namespace std;
class pixel{
            public:
                   unsigned char b;
                   unsigned char g;
                   unsigned char r;
            void display()
            {
                 cout<<r<<" "<<g<<" "<<b<<" ";
                 }
      }p1;
using namespace std;
int main(){
    unsigned char avg;
    fstream file("image.bmp",ios::binary|ios::in|ios::out);

    int start;
    file.seekg(10);
    file.read((char*)&start,4);


    file.seekg(start);
    int i=0;
   while(!file.eof()){
                      cout<<file.tellg();//Remove this and the program doesn't work!
                     file.read((char*)&p1,3);
                     avg=(p1.b+p1.g+p1.r)/3;
                     p1.b=avg;
                     p1.g=avg;
                     p1.r=avg;
                     file.seekg(-3,ios::cur);
                     file.write((char*)&p1,3);
                       }
    file.close();
    getch();
    return 0;
}

当我删除 cout tellg 语句时,循环只运行两次!

我不明白删除 cout 语句有什么不同?

结果:只有一个像素变为灰度。

我在这里找到了我的问题的一个更简单的版本

Reading and writing to files simultaneously?

但是没有找到解决办法……

【问题讨论】:

  • 请记住,人类不善于看到光谱的蓝色端。所以需要为此进行修改。
  • 有关颜色问题,请参阅stackoverflow.com/questions/687261/…。但是不能帮助您解决当前的问题。
  • 我总是对从我刚刚编写的同一流中的文件中读取文件保持警惕。我会尝试读取所有像素,将它们全部处理,然后将它们全部写入。我也不知道为什么它只会运行两次。
  • 这会占用大量内存...接近 3-4 mb.bmp 文件已经太大了...如果您一个一个地处理每个像素,它只需要几个字节.. .

标签: c++ fstream bmp file-handling grayscale


【解决方案1】:

读取和写入std::fstream 时,在读取和写入之间切换时需要查找。原因是文件流共享一个共同的输入和输出位置。为了还支持有效的缓冲,有必要将当前位置通知给相应的其他缓冲区。这是搜索功能的一部分。 tellg() 寻找当前位置。

请注意,在读取和写入之间切换是非常低效的,尤其是当实现得到很好的优化时。您最好写一个不同的文件或更新合理大小的组中的值。

【讨论】:

  • 特别荒谬的是 seekg(-3) 在所有像素的循环中!
  • 这是标准强制要求的吗? I'm seeing differing behaviour across platforms.
  • @LightnessRacesinOrbit:C 和 C++ 文件 I/O 都需要在从读变为写或反之时进行查找:实际要求在 C 标准中。 C++ 流行为是根据 C 要求定义的。在实现缓冲 I/O 并试图使其高效时,对查找的需求变得相当明显:支持在不查找的情况下在读取和写入之间切换具有(至少在我实现 filebuf 时具有)显着成本(对于那些用途没有在输入和输出之间切换)。
  • @DietmarKühl:感谢您的澄清
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-06
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 1970-01-01
  • 2013-01-19
相关资源
最近更新 更多