Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 我使用fread读取BMP上的infoheader。请问我该怎么修?_C_Segmentation Fault_Bmp_Fread - Fatal编程技术网

C 我使用fread读取BMP上的infoheader。请问我该怎么修?

C 我使用fread读取BMP上的infoheader。请问我该怎么修?,c,segmentation-fault,bmp,fread,C,Segmentation Fault,Bmp,Fread,这让我陷入困境,我该怎么解决?我知道我没有进行错误检查,但我猜它们不是必需的,因为它仅限于我的桌面。这显然不可能是EOF。对于infoheader结构,fileheader工作正常。我需要换一条新线路吗 #include <stdio.h> #include <stdlib.h> typedef struct { unsigned char fileMarker1; /* 'B' */ unsig

这让我陷入困境,我该怎么解决?我知道我没有进行错误检查,但我猜它们不是必需的,因为它仅限于我的桌面。这显然不可能是EOF。对于infoheader结构,fileheader工作正常。我需要换一条新线路吗

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    unsigned char fileMarker1;       /* 'B' */                       
    unsigned char fileMarker2;       /* 'M' */ 
    unsigned int   bfSize;             
    unsigned short unused1;           
    unsigned short unused2;           
    unsigned int   imageDataOffset;  /* Offset to the start of image data */
}FILEHEADER; 

typedef struct                       
{ 
    unsigned int   biSize;            
    int            width;            /* Width of the image */ 
    int            height;           /* Height of the image */ 
    unsigned short planes;             
    unsigned short bitPix;             
    unsigned int   biCompression;      
    unsigned int   biSizeImage;        
    int            biXPelsPerMeter;    
    int            biYPelsPerMeter;    
    unsigned int   biClrUsed;          
    unsigned int   biClrImportant;     
}INFOHEADER; 

typedef struct                        
{ 
    unsigned char  b;         /* Blue value */ 
    unsigned char  g;         /* Green value */ 
    unsigned char  r;         /* Red value */ 
 }IMAGECOMPONENT; 

 int fileheadfunc(FILE *image);
 int infoheadfunc(FILE *image);

 int main( int argc, char *argv[] )
 {
    char *filename; /* *threshholdInput = argv[2]; */
    FILE *image;
    int filehead, infohead;
    filename = argv[1];
    /* int threshhold = atoi(threshholdInput); */

    if (argc != 2) 
    {
              printf(" Incorrect Number Of Command Line Arguments\n");
              return(0);
    }

    image = fopen( filename, "r");

        if (image == NULL)
    {
    fprintf(stderr, "Error, cannot find file %s\n", filename);
    exit(1);
    }

    filehead = fileheadfunc(image);
    infohead = infoheadfunc(image);
    fclose(image);

   return(0);             
}

int fileheadfunc(FILE *image)
{
    FILEHEADER *header;
    long pos;

    fseek (image , 0 , SEEK_SET);

    fread( (unsigned char*)header, sizeof(FILEHEADER), 1, image );


    if ( (*header).fileMarker1 != 'B'  || (*header).fileMarker2 != 'M' )
    {
    fprintf(stderr, "Incorrect file format");
    exit(1);
    }

    printf("This is a bitmap!\n");
    pos = ftell(image);
printf("%ld\n", pos);
printf("%zu\n", sizeof(FILEHEADER));

return(0);
}

int infoheadfunc(FILE *image)
{
    INFOHEADER *iheader;

    fseek (image, 0, SEEK_CUR ); 
    fread( (unsigned int*)iheader, sizeof(INFOHEADER), 1, image );

    printf("Width: %i\n", (*iheader).width);
    printf("Height: %i\n", (*iheader).height);

    return(0);
}

实际上,您没有为BMP标头数据结构分配任何存储,例如,您需要更改以下内容:

int fileheadfunc(FILE *image)
{
    FILEHEADER *header;
    long pos;

    fseek(image, 0, SEEK_SET);

    fread((unsigned char*)header, sizeof(FILEHEADER), 1, image);

    ...
为此:

int fileheadfunc(FILE *image)
{
    FILEHEADER header; // <<<
    long pos;

    fseek(image, 0, SEEK_SET);

    fread(&header, sizeof(FILEHEADER), 1, image); // <<<

    ...

此外,正如前面的一条注释所述,如果在结构定义之前没有使用gcc或与gcc兼容的编译器来消除不必要的填充,则需要使用pragma pack1或同等版本。注意:在结构定义之后使用pragma pack来恢复正常的结构填充/对齐。

您实际上没有为BMP标头数据结构分配任何存储,例如,您需要更改以下内容:

int fileheadfunc(FILE *image)
{
    FILEHEADER *header;
    long pos;

    fseek(image, 0, SEEK_SET);

    fread((unsigned char*)header, sizeof(FILEHEADER), 1, image);

    ...
为此:

int fileheadfunc(FILE *image)
{
    FILEHEADER header; // <<<
    long pos;

    fseek(image, 0, SEEK_SET);

    fread(&header, sizeof(FILEHEADER), 1, image); // <<<

    ...

此外,正如前面的一条注释所述,如果在结构定义之前没有使用gcc或与gcc兼容的编译器来消除不必要的填充,则需要使用pragma pack1或同等版本。注意:在结构定义之后使用pragma pack恢复正常的结构填充/对齐。

代码有两个问题:

对齐 出于性能原因,除非另有指示,否则编译器将在其自然边界上排列结构字段,有效地在字节大小字段之间留下未初始化的间隙。加

#pragma pack(1) 
在结构定义之前,您应该很好。测试也很容易:只需打印出结构大小(不带或带pragma包),您就会看到不同之处

分配 正如Paul R已经说过的,您应该为头分配空间,而不仅仅是提供指向结构的指针。fileheadfunc工作的事实是一个巧合,当数据写入到分配的空间之外时,没有任何东西会被破坏

最后一个,只是为了预防:如果您想要将读取结构返回给调用程序,不要只返回指向在函数中分配的结构的指针,因为这将导致与您现在拥有的未分配变量类似的问题。在调用函数中分配它们,并将指向该变量的指针传递给header read函数

编辑关于最后一点的澄清:

不要 做 这将被称为像这样

...
FILEHEADER header;
returnvalue = fileheaderfunc(imagefile,&header);

编辑2:我刚注意到你读报纸的方式不正确。该标题有几种不同的版本,大小不同。因此,在读取文件头之后,您首先需要将4个字节读入一个无符号整数,并根据读取的值选择要使用的正确DIB头结构。不要忘记您已经读取了它的第一个字段!或者告诉用户您遇到了不支持的文件格式。

代码有两个问题:

对齐 出于性能原因,除非另有指示,否则编译器将在其自然边界上排列结构字段,有效地在字节大小字段之间留下未初始化的间隙。加

#pragma pack(1) 
在结构定义之前,您应该很好。测试也很容易:只需打印出结构大小(不带或带pragma包),您就会看到不同之处

分配 正如Paul R已经说过的,您应该为头分配空间,而不仅仅是提供指向结构的指针。fileheadfunc工作的事实是一个巧合,当数据写入到分配的空间之外时,没有任何东西会被破坏

最后一个,只是为了预防:如果您想要将读取结构返回给调用程序,不要只返回指向在函数中分配的结构的指针,因为这将导致与您现在拥有的未分配变量类似的问题。在调用函数中分配它们,并将指向该变量的指针传递给header read函数

编辑关于最后一点的澄清:

不要 做 这将被称为像这样

...
FILEHEADER header;
returnvalue = fileheaderfunc(imagefile,&header);

编辑2:我刚注意到你读报纸的方式不正确。该标题有几种不同的版本,大小不同。因此,在读取文件头之后,您首先需要将4个字节读入一个无符号整数,并根据读取的值选择要使用的正确DIB头结构。不要忘记您已经读取了它的第一个字段!或者告诉用户您遇到了不支持的文件格式。

干杯!我可以使用指针,我可以使用结构,我可以使用fread,但是把它们粘在一起,我就会迷路@康妮:一张实景照片,但你在哪个平台工作?请注意,所有BMP头字段都是小尾端,因此如果您使用的是诸如PowerPC之类的大尾端,则需要进行一些字节交换。否则,如果你仍然卡住了,我建议用你的最新代码发布一个新问题。干杯!我可以使用指针,我可以使用结构,我可以使用fread,但坚持
他们在一起,我就迷路了@康妮:一张实景照片,但你在哪个平台工作?请注意,所有BMP头字段都是小尾端,因此如果您使用的是诸如PowerPC之类的大尾端,则需要进行一些字节交换。否则,如果你仍然被卡住,我建议用你最新的代码发布一个新的问题。我不太确定你在最后一段中的意思,但那可能只是因为我不需要实现它,所以实际上我看不到它,但我会记住它。谢谢你的解释很好。哦,是的,就是这样。我的讲师对此非常着迷。我不能玩结构,这是作业中的既定条件。我可以使用fileheader1和fileheader2检查适当的文件。我很感激你的认真,但这不是必须的。我可以请你接受中解释的答案吗?如果它对你有帮助的话?谢谢。我不太清楚你在最后一段中的意思,但那可能只是因为我不需要实现它,所以实际上我看不到它,但我会记住它。谢谢你的解释很好。哦,是的,就是这样。我的讲师对此非常着迷。我不能玩结构,这是作业中的既定条件。我可以使用fileheader1和fileheader2检查适当的文件。我很感激你的认真,但这不是必须的。我可以请你接受中解释的答案吗?如果它对你有帮助的话?非常感谢。