gcc fgetc从文件中只读取了39个字节

uinbv5nw  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(131)

此程序只读取39个字节。在此之后,所有内容都读取为“-1”

#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;
}

enter image description here
我用fread函数重写了代码。在39字节之后是一些完全不同的字节代码。看起来像是分段文件。但是如果是这样的话,为什么fread和fgets的结果不同呢?

C:\Users\phoenix\Documents\gccex\serial>a.exe
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

读取文件的正确方法是什么?

tsm1rwdh

tsm1rwdh1#

在Microsoft Windows上,二进制文件应该以二进制模式("rb")打开,而不是以文本模式("r")打开。WAVE文件是一个二进制文件。
在此之后,所有内容均显示为“-1”
此语句不正确。您不再阅读任何内容。函数fgetc正在返回宏常量EOF,在大多数平台上定义为-1。如果您检查EOF,则应将循环更改为以下内容,以使其变得明显:

for(int i=0;i<200;i++)
    {
        int a = fgetc(file); //the type must be int, not char

        if ( a == EOF )
        {
            printf( "EOF\n" );
            break;
        }

        printf("%hhX ",a);
    }

fgetc返回EOF时,这意味着已经到达文件尾或者发生了错误。在这种情况下,这是由于文件尾。
在Microsoft Windows中,当以文本模式打开文件时,字符代码0x1A被解释为文件的结尾。根据您发布的屏幕截图,您的文件恰好在文件偏移量0x28处具有值0x1A。这就是您最多只能读取文件偏移量0x27的原因(十进制的39)。若要修正此问题,请以二进制模式(而非文字模式)开启档案。

oug3syen

oug3syen2#

“什么是正确的读取文件的方法?”
注解示例如下:

// #include <windows.h> // Not needed for this program
#include <stdio.h>

int main() {
    char *fname = "Eva.wav"; // re-usable string

    FILE *file = fopen( fname, "rb" ); // NB: "binary mode" for Windows
    if( file == NULL ) {
        fprintf( stderr, "Cannot open '%s'\n", fname ); // See?
        exit( EXIT_FAILURE ); // do not continue
    }
    
    unsigned char buf[ 200 ]; // OP wants to 'sniff' first 200 bytes

    // "correct" way to read bytes
    // Could use loop, reading 1, 20, or 50 bytes at a time. Why?
    size_t nRead = fread( buf, sizeof buf[0], sizeof buf, file );

    fclose( file ); // close when no longer needed

    // only bytes loaded, not quantity expected
    for( size_t i = 0; i < nRead; i++ )
        printf( "%02X ", buf [ i ] ); // "old school". may be antiquated

    return 0;
}

相关问题