【问题标题】:Open a png file and read it's hex values in C打开一个 png 文件并在 C 中读取它的十六进制值
【发布时间】:2013-03-19 21:10:32
【问题描述】:

我正在尝试读取具有任何文件类型结尾的文件,并根据它的十六进制值确定它是否是 PNG 文件。

到目前为止,我已经尝试了两条不同的路径,但都没有奏效。

  • 首先我读取前 16 个字符,因为前 8 个十六进制值确定它是否具有正确的标题。然后我尝试将其分开,并读取与此处其他线程中显示的十六进制值一样。
  • 另一个我只想读取前两个值并确定它是否是十六进制值,甚至看看它是否工作。不是。

代码:

int IS_PNG_FILE(char *name)
{
    FILE *dat = fopen (name, "rt");
    if (dat == NULL) return 1;
    int data_point;

    char buf[16], a[16];
    fgets(buf, 16, dat);
    printf("%s\n", buf);
    int i, b;
    for (i=0; i<16; i++)
    {
        sscanf(&buf[i], "%2x", &b);
        a[i] = b;
        i += 2;
    }
    printf("%d\n", a);


    fscanf(dat, "%2x", &data_point);
    printf("%d\n", data_point);

    fclose(dat);
    return 0;
}

【问题讨论】:

  • fopen (name, "rt")?改用"rb"
  • 它仍然只是返回最大数或-2。
  • PNG 文件不是文本。它们中的字节根本不是十六进制的“字符串”,所以sscanf 不会像你想的那样做,这不是一种有用的技术。您已经读取了前 16 个字节(很好)——您需要将值中这些字节的值直接与您期望的数字进行比较。
  • 那么,关于 strncmp(buf, "80504e470d0a1a0a")?
  • 您似乎对十六进制和二进制有些不了解。 PNG 文件不是以十六进制编码的,而是以二进制格式编码的。这种二进制格式,当人类查看时,通常会转换为十六进制以使内容更易于阅读,但它们实际上是相同的。所以“80504e470d0a1a0a”不是该数字表示的十六进制值,而是用 ANSI 编码的字母和数字字符串。如果您仍然感到困惑,我很乐意提供进一步的帮助。

标签: c png hex


【解决方案1】:

为了从文件中读取二进制字节,请使用fread:

函数 fread() 从 stream 指向的流中读取数据的 nmemb 元素,每个 size 字节长,并将它们存储在 ptr 给定的位置。

类似:

unsigned char head[8];

fread(head, sizeof(head), 1, dat);

您可以检查返回值以验证是否实际读取了 8 个字节。

然后使用 memcmp 进行比较

unsigned char signature[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};

if (!memcmp(signature, head, 8))
{
    ...
}

【讨论】:

    猜你喜欢
    • 2015-05-01
    • 2011-10-07
    • 2015-12-09
    • 2015-01-26
    • 2012-04-04
    • 2015-12-20
    • 2014-02-25
    • 1970-01-01
    • 2020-07-27
    相关资源
    最近更新 更多