C++ 解析文件头
我正在处理图像。我想从标题中提取它的宽度和高度 宽度在位置处表示C++ 解析文件头,c++,C++,我正在处理图像。我想从标题中提取它的宽度和高度 宽度在位置处表示 size 4B width 4B height 它们以特定的索引表示 我试着解析它并用代码解压它 ifstream f(name, ios::binary | ios:: in ); // reading a file in binary ostringstream ob; if ( f.fail()){ // fail test return false;
size
4B width
4B height
它们以特定的索引表示
我试着解析它并用代码解压它
ifstream f(name, ios::binary | ios:: in ); // reading a file in binary
ostringstream ob;
if ( f.fail()){ // fail test
return false;
}
f.seekg (0, f.end);
int length = f.tellg(); // length of the file
memory = new char[length]; // allocate array of chars
f.read (memory, length); // read the content of the file into an array
f.seekg (0, f.beg); // point back at the beginning of the file.
它们每个都有4B,所以使用for循环
for ( int i = index ; i <4 ;i++){
cout << hex<< memory[i];
}
for(int i=index;istd::cout
将打印作为字符传递的数据,如果数据是char
,请在打印前尝试强制转换
for ( int i = 0 ; i < 4 ; i++) {
cout << hex<< (int)(unsigned char)memory[index + i];
}
for(int i=0;i<4;i++){
cout您在读取文件后而不是之前查找文件的开头。您需要切换read()
和seekg()
:
为了快速回答标题中所述的问题,通过查看指定的输入文件,您可以简单地读取三行,跳过第一行,然后从下面两行中分别提取一个整数
大概是
int width, height;
std::string input;
std::istringstream is;
std::getline(stream, input); // One line for the "size" string
std::getline(stream, input); // One line for the width
is.str(input)
is >> width;
std::getline(stream, input); // One line for the height
is.str(input)
is >> height;
如果文件中有多个类似的条目,则在循环中执行上述操作
如果文件实际上不包含您显示的文本,只包含数字,则更简单:
int width, height;
stream >> width >> height;
或者如果您有多个条目
while (stream >> width >> height) { ... }
你没有提供太多的信息,所以这里有点猜测,但这是我阅读文件的方法:
主要功能是,不使用手动内存分配,使用std::vector
(它的作用是什么)。还可以将数据从字符数组复制到从正确类型转换的变量中。这可以确保对齐正确(从不转换到字符数组中)。另一种方法可能是直接从文件读取正确类型的变量,并将其转换为char*
int main(int, char* argv[])
{
// first parameter needs to be file name
std::string name = argv[1] ? argv[1]:"";
std::ifstream ifs(name, std::ios::binary|std::ios::ate); // open at end
if(!ifs)
{
std::cerr << std::strerror(errno) << '\n';
return EXIT_FAILURE;
}
if(ifs.tellg() < 8) // too small
{
std::cerr << "Bad image file, too short" << '\n';
return EXIT_FAILURE;
}
// Don't allocate memory manually, use a container
std::vector<char> image(ifs.tellg()); // big enough for whole file
ifs.seekg(0); // back to beginning
if(!ifs.read(image.data(), image.size()))
{
std::cerr << std::strerror(errno) << '\n';
return EXIT_FAILURE;
}
// copy raw data into variables
std::uint32_t width; // 4 bytes wide integer
std::uint32_t height; // 4 bytes wide integer
std::copy(&image[4], &image[ 8], (char*)&width); // offset 4 bytes
std::copy(&image[8], &image[12], (char*)&height); // offset 8 bytes
// at this point a lot depends on the system architecture and
// how the number is stored in the file. The documentation
// should tell you if it is little-endian or big-endian
// you may have to do manual jiggery-pokery
// to change endienness
std::cout << "width : " << width << '\n';
std::cout << "height: " << height << '\n';
}
intmain(int,char*argv[]
{
//第一个参数必须是文件名
std::string name=argv[1]?argv[1]:“”;
std::ifstream ifs(名称,std::ios::binary | std::ios::ate);//在末尾打开
如果(!ifs)
{
什么是index
?你是说for(inti=index;我从来没有使用过新类型[count]
,改用vector
。无论如何,你必须为你的问题提取一个最小的例子,以符合网站规则。ATM这是离题的。你有标题格式的链接吗?是高度和宽度的前两个值吗?文档是否告诉你“endian”是什么是用来存储数字的吗?图像是以原始格式存储的,偏移量4和4B是宽度,偏移量8和4B是高度。你知道图像是如何写出来的吗?你有任何关于该格式的文档吗?
int width, height;
stream >> width >> height;
while (stream >> width >> height) { ... }
int main(int, char* argv[])
{
// first parameter needs to be file name
std::string name = argv[1] ? argv[1]:"";
std::ifstream ifs(name, std::ios::binary|std::ios::ate); // open at end
if(!ifs)
{
std::cerr << std::strerror(errno) << '\n';
return EXIT_FAILURE;
}
if(ifs.tellg() < 8) // too small
{
std::cerr << "Bad image file, too short" << '\n';
return EXIT_FAILURE;
}
// Don't allocate memory manually, use a container
std::vector<char> image(ifs.tellg()); // big enough for whole file
ifs.seekg(0); // back to beginning
if(!ifs.read(image.data(), image.size()))
{
std::cerr << std::strerror(errno) << '\n';
return EXIT_FAILURE;
}
// copy raw data into variables
std::uint32_t width; // 4 bytes wide integer
std::uint32_t height; // 4 bytes wide integer
std::copy(&image[4], &image[ 8], (char*)&width); // offset 4 bytes
std::copy(&image[8], &image[12], (char*)&height); // offset 8 bytes
// at this point a lot depends on the system architecture and
// how the number is stored in the file. The documentation
// should tell you if it is little-endian or big-endian
// you may have to do manual jiggery-pokery
// to change endienness
std::cout << "width : " << width << '\n';
std::cout << "height: " << height << '\n';
}