c - Problemer med at bruge fread () på stdin under win32

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at analysere data fra stdin i binær tilstand under Win32.
Den første ting, min kode gør, er at tjekke efter en 4byte header i starten:


int riff\_header;
fread(&riff\_header, sizeof(riff\_header), 1, ifp);
//  'RIFF' = little-endian
if (riff\_header != 0x46464952) {
    fprintf(stderr, "wav2msu: Incorrect header: Invalid format or endianness
");
    fprintf(stderr, "         Value was: 0x\%x
", riff\_header);
    return -1;
}


stdin er blevet skiftet til binær tilstand før læsning fra den:


if (*argv[argc-1] == '-') {
    fprintf(stderr, "Reading from stdin.
");
    infile = stdin;
    // We need to switch stdin to binary mode, or else we run
    // into problems under Windows
    freopen(NULL, "rb", stdin);
}


Denne kode fungerer fint under Linux, men på Win32 (specifikt Windows XP) synes fread kun at læse en enkelt byte og dermed få evalueringen til at mislykkes.
Eksempel:


> ffmeg.exe -i ..	est.mp3 -f wav pipe:1 2> nul |..foo.exe -o test.bin -
Reading from stdin.
foo: Incorrect header: Invalid format or endianness
     Value was: 0x4


Hvad gør jeg forkert?

Bedste reference


På http://pubs.opengroup.org/onlinepubs/009695399/functions/freopen.html Jeg har fundet følgende: [17]



  Hvis filnavn er en nullpeger, skal funktionen freopen () forsøge at
  ændre tilstanden af ​​strømmen til den, der er angivet i tilstanden, som om
  navnet på den fil, der for øjeblikket er forbundet med streamen, var blevet brugt.
  I dette tilfælde behøver den filbeskrivelse, der er forbundet med strømmen, ikke
  lukkes, hvis opkaldet til freopen () lykkes. det er
  implementerings-defineret, hvilke ændringer af tilstand der er tilladt (hvis nogen)
  og under hvilke omstændigheder.



Måske bør du kontrollere, om ændringsmodusen (fra tekst til binær) er tilladt af kompilatoren og bibliotekerne du bruger. Hvilken compiler bruger du?


Opdater/resumé


Ved hjælp af MinGW kan du ringe setmode () for at skifte tilstanden til stdin streamen.
Du skal indstille tilstanden til \_O\_BINARY, som er defineret i fcntl.h.
For mere information se f.eks. http://gnuwin32.sourceforge.net/compile.html[18]

Andre referencer 1


Ifølge MSDN-dokumentationen er det ikke tilladt at videregive NULL til path parameteren til freopen, så opkaldet til freopen er næsten helt sikkert fejlagtigt, har du tjekket returneringsværdien og værdien af ​​errno? C89 angiver ikke opførelsen af ​​freopen når path er NULL; C99 gør, men Microsoft C runtime er ikke (og hævder ikke at være) C99-kompatibel. [19]


Hvis du virkelig skal læse binær info fra stdin, skal du muligvis bruge platformspecifik kode og læse de rå binære data direkte med ReadFile på filen GetStdHandle(STD\_INPUT\_HANDLE). [20]]] [21]