我正在编写程序以读取bmp标头。我编写了一些在main
中都可用的代码。如何实现此代码本身的功能,然后将其实现到main上?
这里是整个代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdin.h>
struct bmp_header {
uint16_t type;
uint32_t size;
uint16_t reserved1;
uint16_t reserved2;
uint32_t offset;
uint32_t dib_size;
uint32_t width;
uint32_t height;
uint16_t planes;
uint16_t bpp;
uint32_t compression;
uint32_t image_size;
uint32_t x_ppm;
uint32_t y_ppm;
uint32_t num_colors;
uint32_t important_colors;
};
void read_bmp(FILE *BMPFile,struct bmp_header* Header) {
fread(&(Header->type), 2, 1, BMPFile);
fread(&(Header->size),4,1,BMPFile);
fread(&(Header->reserved1),2,1,BMPFile);
fread(&(Header->reserverd2),2,1,BMPFile);
fread(&(Header->offset),4,1,BMPFile);
fread(&(Header->dib_size),4,1,BMPFile);
fread(&(Header->width),4,1,BMPFile);
fread(&(Header->height),4,1,BMPFile);
fread(&(Header->planes),2,1,BMPFile);
fread(&(Header->bpp),2,1,BMPFile);
fread(&(Header->compression),4,1,BMPFile);
fread(&(Header->image_size),4,1,BMPFile);
fread(&(Header->x_ppm),4,1,BMPFile);
fread(&(Header->y_pp),4,1,BMPFile);
fread(&(Header->num_colors),4,1,BMPFile);
fread(&(Header->important_colors),4,1,BMPFile);
}
int main() {
FILE *BMPFile = fopen("image.bmp","rb");
if(BMPFile == NULL)
{
return;
}
struct bmp_header* Header;
read_bmp(BMPFile,Header);
fclose(BMPFile);
return 0;
}
该程序版本的相关部分以及在main
中的所有读取操作均按预期工作,在下面报告,
int main( void )
{
FILE *BMPFile = fopen ("lenna.bmp", "rb");
if (BMPFile == NULL)
{
return 0;
}
struct bmp_header Header;
memset(&Header, 0, sizeof(Header));
fread(&Header.type, 2, 1, BMPFile);
fread(&Header.size),4,1,BMPFile);
fread(&Header.reserved1),2,1,BMPFile);
fread(&Header.reserverd2),2,1,BMPFile);
fread(&Header.offset),4,1,BMPFile);
fread(&Header.dib_size),4,1,BMPFile);
fread(&Header.width),4,1,BMPFile);
fread(&Header.height),4,1,BMPFile);
fread(&Header.planes),2,1,BMPFile);
fread(&Header.bpp),2,1,BMPFile);
fread(&Header.compression),4,1,BMPFile);
fread(&Header.image_size),4,1,BMPFile);
fread(&Header.x_ppm),4,1,BMPFile);
fread(&Header.y_pp),4,1,BMPFile);
fread(&Header.num_colors),4,1,BMPFile);
fread(&Header.important_colors),4,1,BMPFile);
/* Header fields print section */
/* ... */
}
您必须创建struct bmp_header *类型的函数。接下来,在函数中创建struct bmp_header指针,并为返回的引用分配内存(头大小== 54B)。
无论何时工作代码停止工作,集中精力在代码的两个版本之间的更改会很有用。那么,为什么您的原始代码可以正常工作?看起来像这样:
int main( void )
{
FILE *BMPFile = fopen ("lenna.bmp", "rb");
if (BMPFile == NULL)
{
return 0;
}
struct bmp_header Header;
memset(&Header, 0, sizeof(Header));
fread(&Header.type, 2, 1, BMPFile);
...
}
Header
类型的struct bmp_header
(作为局部变量)。 通过这种方式,可以确定在程序的整个生命周期中分配结构。 memset
设为0Header
的字段地址直接传递给fread
在新版本的程序中,您定义的功能为
void read_bmp(FILE *BMPFile,struct bmp_header* Header);
所以您需要一个指向struct bmp_header
的指针才能传递给它。因此,您声明
struct bmp_header *标头;
并呼叫read_bmp(BMPFile,Header);
。
工作版本有什么不同?好吧,指针!声明一个指向编译器的指针,该指针包含一个地址,在本例中为read_bmp()
所需结构的地址。
但是您从不向编译器说地址是什么,以便fread
中的read_bmp()
将写入随机位置,从而导致分段错误。
您需要将[ read_bmp()
地址传递给struct bmp_header
,并且您具有两个选项。
Header
,并通过read_bmp()
运算符将其地址传递给&
。这应该是您的第一次尝试,因为它确实与您的工作解决方案相似。 struct bmp_header Header;
read_bmp(BMPFile, &Header);
您可以将
Header
声明为指针,但是您将需要通过malloc
动态分配其内存:
struct bmp_header * Header = malloc(sizeof(struct bmp_header));
read_bmp(BMPFile, Header);