Home > database >  fgetc read only 39 bytes from file
fgetc read only 39 bytes from file

Time:09-05

This programm reads only 39 bytes. After this everything reads as '-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

I rewrite code using fread function. After 39 byte comes something absolute other byte code. Looks like segmented file. But if it so, why fread and fgets result are different?

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

What is the right way to read file?

CodePudding user response:

On Microsoft Windows, binary files should be opened in binary mode ("rb"), not text mode ("r"). A WAVE file is a binary file.

After this everything reads as '-1'

This statement is incorrect. You are no longer reading anything. The function fgetc is returning the macro constant EOF, which is defined as -1 on most platforms. This should become apparant if you check for EOF, by changing your loop to the following:

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

When fgetc returns EOF, this means that either end-of-file has been reached or an error has occurred. In this case, it is due to end-of-file.

On Microsoft Windows, when a file is opened in text mode, the character code 0x1A is interpreted as the end of the file. According to your posted screenshot, your file happens to have the value 0x1A at file offset 0x28. That is the reason why you can only read up to file offset 0x27 (39 in decimal) in the file. To fix this, open the file in binary mode instead of text mode.

CodePudding user response:

"What is the right way to read file?"

Annotated example below:

// #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
    }
    
    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( "X ", buf [ i ] ); // "old school". may be antiquated

    return 0;
}
  •  Tags:  
  • c gcc
  • Related