c++ - 从二进制文件读取时 C++ 跳过字节
问题描述
我整理了一些 C++ 代码来从某些文件中提取 PNG。它不是最精致的,但它似乎跳过了某些空字节。
这是代码:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream source("source.win", ios::out | ios::binary);
char current[] = { 0,0,0,0 };
char header[] = { (char)137, 'P', 'N', 'G' };
char footer[] = { 'I', 'E', 'N', 'D' };
char c = 0;
int n = 0;
ofstream out("png0.png", ios::out | ios::binary);
out.close();
while (source >> c) {
if (out.is_open()) {
out << c;
}
current[0] = current[1];
current[1] = current[2];
current[2] = current[3];
current[3] = c;
if (current[0] == (char)137 &&
current[1] == 'P' &&
current[2] == 'N' &&
current[3] == 'G') {
n++;
out.open("png" + to_string(n) + ".png", 6);
out << (char)137 << "PNG";
}
if (current[0] == 'I' &&
current[1] == 'E' &&
current[2] == 'N' &&
current[3] == 'D') {
out.close();
}
}
}
这是它输出的文件的开头,以及它应该输出的实际文件的开头:
89 50 4E 47 1A 00 00 00 49 48 44 52 00 00 01 00
00 00 01 00 08 06 00 00 00 5C 72 A8 66 00 00 5F
49 44 41 54 78 9C ED DD 6F 88 65 75 ...
对比
89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52
00 00 01 00 00 00 01 00 08 06 00 00 00 5C 72 A8
66 00 00 0A 5F 49 44 41 54 78 9C ED DD 6F 88 65
75 ...
编辑:我从 >> 切换到 get() 并从 << 切换到 put(),但0A
仍然被放置为0D 0A
解决方案
该程序不会删除空值,而是删除空白字符。这是因为 的默认行为operator>>
是丢弃空格。注意0A
s(换行)和0D
s(回车)是如何被去掉的。您还应该发现20
(空格)、0C
(换页)、09
(制表符)和 08
(垂直制表符)也不见了。
hack 修复是添加std::noskipws
(ie source >> std::noskipws >> c
) 以指示流不跳过空格。但更好的方法是首先不要进行格式化读写,std::istream::get()
而是更喜欢std::ostream::put()
。
也就是说,一旦您找到感兴趣区域的开始,您应该考虑一次切换到std::istream::read()
并std::ostream::write()
移动多个字节的整个块。
推荐阅读
- git - 在 git push origin main 之后,什么也没有发生
- google-apps-script - 获取#错误!和#NAME?当我在 Google Apps 脚本中使用 .setFormula () 时,在单元格表中
- cassandra - Cassandra更新列应该更新列值而不是ttl?
- r - 根据组和当前分类变量创建新的分类变量
- arrays - 如何存储 for 循环结果并在命令中引用?
- javascript - 如何为游戏循环进行类方法递归?
- javascript - Bootstrap Carousel 中的字幕以对角线方式而不是垂直方式进行动画处理
- c++ - 找不到 Qt C++ 指定模块中的 MATLAB 引擎
- docker-compose - Nuxt dev + docker-compose + nginx 代理管理器错误
- python - 是否有一种通用方法可以用python中不同程度的嵌套级别替换嵌套字典中的值?