在不使用Ignore()读取二进制文件(C++)时忽略N个字节

Ignore N bytes when reading binary file(C++) without using ignore()?

本文关键字:字节 C++ 读取 Ignore 二进制文件      更新时间:2023-10-16

对于一个学校项目,我们在某个函数中从一个BMP格式的二进制文件中读取像素。像素是来自对象的像素类型的2D阵列。这里的目标是从二进制文件中读取像素的X行和Y列。但是,每行像素后面都有一些填充,可以使用函数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)));

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

std::ofstream ofs;
ofs.open("out.txt");
ofs<<"test stringn";
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)0,但您正在尝试使用可以更大的大小。还有一个类似的问题-如何写';n';在python 中将字符复制到类似ostream的位置

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,或小于零。