在不使用ignore()的情况下读取二进制文件(C ++)时忽略N个字节?

时间:2017-11-19 18:29:55

标签: c++ input stream binary binaryfiles

对于学校项目,我们在某个函数中读取二进制文件中的像素,这是一种BMP格式。像素是来自对象的Pixel类型的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;在下一个函数中,我必须拍摄一张图像并将其写入二进制文件中,并将二进制文件放在二进制文件中,其中有填充。

这有效吗?

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

2 个答案:

答案 0 :(得分:0)

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);

另一种可能性 - 与streamoff结合的streampos

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

答案 1 :(得分:0)


$> 123 instanceof (123).constructor
$< false
$> new Number(123) instanceof (123).constructor
$< true

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

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

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); 永远不等于或大于4,或小于零。