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

fgetc只读39字节、fread结果异常,如何正确读取文件?

解决WAV文件读取异常:fgetc读取截断与fread异常的问题

问题现象

  • 使用fgetc读取Eva.wav文件时,仅能读取前39字节,后续读取结果全为-1
  • 改用fread后,读取到39字节后出现大量FFxx格式的异常字节码,不清楚两种读取方式结果差异的原因,也不知道正确的文件读取姿势

用户原fgetc代码:

#include <windows.h>
#include <stdio.h>
int main()
{
    FILE *file =fopen("Eva.wav","r");
    if (file==NULL)
        printf("heresy read!");
    
    for(int i=0;i<200;i++)
    {
        char a = fgetc(file);
        printf("%hhX ",a);
    }
    fclose(file);
    return 0;
}

fread改写后的输出(部分):

52 49 46 46 46 FF8C FFA3 0 57 41 56 45 66 6D 74 20 10 0 0 0 1 0 1 0 44 FFAC 0 0 44 FFAC 0 0 1 0 8 0 4C 49 53 54 FF86 FFAA 6A FFFB FFFE 7F 0 0 FF88 2C 40 0 0 0 0 0 0 0 0 0 0 0 0 0 10 15 40 0 0 0 0 0 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11 0 1 10 0 0 0 0 60 7 FF96 0 0 0 0 0 FF86 FFAA 6A FFFB FFFE 7F 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 FFB0 16 40 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 13 FF96 0 0 0 0 0 FF83 16 40 0 0 0 0 0 1 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 70 13 FF96 0 0 0 0 0 FFB0 16 40 0 0 0 0 0 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FF99 17 40 0 0 0 0 0 10 0 0 0 0 0 0 0 FF99 16 40 0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0 0 0 0 0

问题根源

  1. 文本模式触发的截断:Windows平台下,fopen用"r"打开是文本模式,这种模式会把字节0x1A(ASCII的EOF控制字符)当成文件结束标志。你的WAV文件刚好在第39字节左右包含这个字符,所以fgetc读到这里就直接返回EOF(即-1),后续读取全是-1。
  2. 有符号char的符号扩展:fgetc返回的是int类型(范围-1到255),你把它存到char里——Windows下默认char是有符号类型,当读取的字节值大于0x7F时,会被转换成负数(比如0x8C变成-116,以补码表示就是0xFF8C),这就是fread输出里大量FFxx的原因,本质是符号扩展导致的显示异常,不是文件分段。

正确的读取方式

核心要点

  • 打开二进制文件必须用二进制模式:fopen("Eva.wav", "rb"),避免文本模式的特殊字符处理
  • 用unsigned char存储读取的字节,防止符号扩展导致的负数显示
  • 读取时要正确判断文件结束(fgetc返回EOF或fread返回的读取数量小于请求数量)

修正后的fgetc版本代码

#include <windows.h>
#include <stdio.h>
int main()
{
    FILE *file = fopen("Eva.wav", "rb");
    if (file == NULL)
    {
        printf("heresy read!");
        return 1;
    }
    
    int ch;
    for(int i = 0; i < 200; i++)
    {
        ch = fgetc(file);
        if (ch == EOF)
            break;
        printf("%02X ", (unsigned char)ch);
    }
    fclose(file);
    return 0;
}

修正后的fread版本代码

#include <windows.h>
#include <stdio.h>
int main()
{
    FILE *file = fopen("Eva.wav", "rb");
    if (file == NULL)
    {
        printf("heresy read!");
        return 1;
    }
    
    unsigned char buf[200];
    size_t read_count = fread(buf, 1, sizeof(buf), file);
    for(size_t i = 0; i < read_count; i++)
    {
        printf("%02X ", buf[i]);
    }
    fclose(file);
    return 0;
}

现在两种方式读取的结果会完全一致,都能正确读取WAV文件的二进制内容,不会出现截断或异常字节显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:52:06