You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不依赖第三方库用C语言读取PNG文件签名输出异常咨询

异常原因
  • 数组下标越界:C语言数组索引从0开始,你申请了长度为8的内存空间,合法访问下标范围为0~7,代码中从buf[1]开始访问到buf[8],buf[8]属于越界访问非法内存,会读取到不可预期的垃圾值。
  • 文件打开模式错误:使用"r"文本模式打开PNG二进制文件,Windows系统下文本模式会自动对换行符做转义处理,篡改原始二进制字节内容,读取二进制文件必须使用"rb"二进制模式。
  • 语法错误:所有printf语句的格式字符串缺失左双引号,属于编译期语法错误,会导致实际运行逻辑不符合预期。
  • 输出格式错误:PNG签名前几个字节属于非可打印ASCII字符,使用%c输出会显示为乱码符号,无法和规范的十进制/十六进制值做比对。
修复方案
  • 调整数组索引范围为0~7,访问buf[0]到buf[7]
  • 将fopen的打开模式改为"rb"
  • 补全所有printf语句缺失的左双引号
  • 将输出格式改为%02X输出十六进制,或者%d输出十进制,方便和规范值比对
  • 额外新增读取长度校验,避免读取过小的非PNG文件
修复后的完整代码
#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 8

int main(int argc, char **argv){
    if(argc != 2) {
        printf("Usage: %s <png file>\n", argv[0]);
        return 1;
    }
    
    unsigned char *buf = (unsigned char *)malloc(MAX_SIZE);
    if(!buf) {
        fprintf(stderr, "Couldn't allocate memory\n");
        return 1;
    }
    
    FILE *f = fopen(argv[1], "rb");
    if(!f) {
        perror("fopen");
        free(buf);
        return 1;
    }
    
    int size = fread(buf, 1, MAX_SIZE, f);
    if(size != MAX_SIZE) {
        fprintf(stderr, "File is too small to be a PNG\n");
        fclose(f);
        free(buf);
        return 1;
    }

    // 输出十六进制签名
    printf("PNG signature hex: ");
    for(int i=0; i<MAX_SIZE; i++) {
        printf("%02X ", buf[i]);
    }
    printf("\n");

    // 输出十进制签名
    printf("PNG signature dec: ");
    for(int i=0; i<MAX_SIZE; i++) {
        printf("%d ", buf[i]);
    }
    printf("\n");
    
    fclose(f);
    free(buf);
    system("pause");
    return 0;
}

修复后运行正常会输出如下结果,和PNG规范完全一致:

PNG signature hex: 89 50 4E 47 0D 0A 1A 0A 
PNG signature dec: 137 80 78 71 13 10 26 10 

内容的提问来源于stack exchange,提问作者NULL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 09:15:04