C 可以使用fread()确定文件类型吗?

C 可以使用fread()确定文件类型吗?,c,fwrite,fread,C,Fwrite,Fread,我试图使用fread()来确定文件是否为jpeg,我的想法是使用fread()读取文件头以确保它是jpeg,如果是,则复制文件。我知道标准jpeg头是0xff 0xd8 0xff 0xe(0到f),所以我制作了一个程序来读取文件的前四个字节 #include <stdio.h> #include <stdint.h> typedef uint8_t BYTE; int main (int argc, char *argv[]) { FILE *in = fop

我试图使用
fread()
来确定文件是否为jpeg,我的想法是使用
fread()
读取文件头以确保它是jpeg,如果是,则复制文件。我知道标准jpeg头是
0xff 0xd8 0xff 0xe(0到f)
,所以我制作了一个程序来读取文件的前四个字节

#include <stdio.h>
#include <stdint.h>

typedef uint8_t BYTE;

int main (int argc, char *argv[])
{
    FILE *in = fopen(argv[1], "rb");
    
    FILE *out = fopen("output.jpg", "wb");
    
    BYTE buffer [4096];
    
    while (fread(buffer, 1, sizeof(buffer), in))
    {
        if ((buffer[0] == 0xff) & (buffer[1] == 0xd8) & (buffer[2] == 0xff) & ((buffer[3] & 0xf0) == 0xe0))
        {
            fwrite(buffer, 1, sizeof(buffer), out);
        }
    }
    
    fclose(in);
    fclose(out);
}

在本例中,
output.jpg
确实正确打开,这使我认为是我试图使用
fread()
检查导致问题的文件类型。我应该使用不同的函数,还是只是格式不正确?

这里有两个问题

您的程序在循环中从文件中一次最多读取4KB,在写入文件之前,您要检查每个4KB块的前4个字节,以查看它是否为jpeg头。您只希望在首次读取文件时执行一次。如果通过检查,则保持循环读写,否则将中断


另一个问题是您总是将
sizeof(buffer)
字节写入文件。
fread
函数读取的字节数可能小于此值,如果是这种情况,您将写入不应该写入的额外数据。您需要捕获
fread
的返回值以了解读取了多少,然后将其用作写入
fwrite

&
的长度应为
&
。前者是“按位and”,而后者是“逻辑and”。更重要的是,
if
条件检查应该只执行一次,而不是针对每个循环。因为根据定义,头仅位于文件的开头,而不是读取的所有数据块。此外,请检查
fread
的返回值,并且不要写入超过实际读取的字节。Hi@kaylum,按位和逻辑“and”之间的区别是什么?
while (fread(buffer, 1, sizeof(buffer), in))
        {
            fwrite(buffer, 1, sizeof(buffer), out);
        }