【问题标题】:Ignore N bytes when reading binary file(C++) without using ignore()?读取二进制文件(C++)时忽略 N 个字节而不使用忽略()?
【发布时间】:2017-11-19 18:29:54
【问题描述】:

对于一个学校项目,我们在某个函数中从二进制文件中读取像素,这是一种 BMP 格式。像素是来自对象的 Pixel 类型的 2D 数组。这里的目标是从二进制文件中读取 X 行和 Y 列像素。但是每行像素后面都有一些padding,可以用函数calculatePadding()计算,返回类型为unsigned。

我们要做的是逐行读取二进制文件并跳过每一行之后的填充,因为我们将像素存储在另一个变量中。这是我到目前为止所做的:

for (int i = image.height - 1; i >= 0; i--) {
    for (unsigned j = 0;j < image.width; j++) {
        file.read((char*)&image.pixels[i][j], sizeof(Pixel));
    }
    fichier.seekg(sizeof(calculatePadding(image)) + tellp() , ios::beg);
}

我的问题是最后一行(在最后一个右括号之前)。我知道我必须通过添加光标的当前位置和填充的大小来将光标向前设置。但是,我怎样才能添加一个无符号和 streampos?我不明白我应该进行什么转换。我们不允许使用ignore()

感谢您的帮助!

另外,顺便说一句,如何将“0”写入二进制文件?在下一个函数中,我必须拍摄一张图像并将其写入二进制文件,然后在有填充的二进制文件中放入“0”。

这行得通吗?

int zero = 0;
file.write((char*)&zero, sizeof(calculatePadding(image)));

【问题讨论】:

  • 填充总是小于 4 个字节。我只需制作一个 4 字节数组并将填充读入其中。这很简单,你可以在写作时使用相同的技术。
  • sizeof 是干什么用的?

标签: c++ input stream binary binaryfiles


【解决方案1】:

afaik 没有可移植的方法来求和/减去 streampos 和数字。 但可以通过两个步骤实现相同的目标: 1. 设置相对于开头的位置(使用streampos) 2. 相对于当前位置设置位置(无符号)

std::ofstream ofs;
ofs.open("out.txt");
ofs<<"test string\n";
auto opos = ofs.tellp();
std::ifstream ifs;
ifs.open("in.txt");
ifs.seekg(opos, std::ios::beg);
ifs.seekg(10/* your additional offset*/, std::ios::cur);

另一种可能性 - 将 streampos 与 streamoff 相加

ifs.seekg(opos + std::streamoff(10/* your additional offset*/), std::ios::beg);

大约为 0。您可以使用 put /write 方法写入一个或多个字节(字符)。你的方法不正确。您只有 sizeof(int) 零,但您正在尝试使用可以更大的大小。 有一个类似的问题-How to write 'n' copies of a character to ostream like in python

【讨论】:

    【解决方案2】:
    sizeof(calculatePadding(image))//?
    

    sizeof 运算符肯定是错误的。 sizeof(n) 其中n 是任何整数始终是常量,通常为 4 或 8,具体取决于操作系统。

    在这种情况下,对于 24 位位图 (0,1,2,3),填充介于 0 到 4 个字节之间,它应该与 image.width % 4 相同。您只需要在读取每一行后跳过那么多字节:

    int padding = calculatePadding(image);
    for (int i = image.height - 1; i >= 0; i--) {
        for (unsigned j = 0;j < image.width; j++) {
            file.read((char*)&image.pixels[i][j], sizeof(Pixel));
        }
        file.seekg(padding, ios::cur);
    }
    

    要向输出文件添加填充,请使用:

    char buf[4]={0};
    fileout.write(buf, padding);
    

    这是假设 padding 永远不会等于或大于 4,或小于零。

    【讨论】:

      猜你喜欢
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-18
      • 1970-01-01
      相关资源
      最近更新 更多