C read binary stdin

前端 未结 8 2195
难免孤独
难免孤独 2020-11-30 04:51

I\'m trying to build an instruction pipeline simulator and I\'m having a lot of trouble getting started. What I need to do is read binary from stdin, and then store it in me

相关标签:
8条回答
  • 2020-11-30 05:23

    I had it right the first time, except, I needed ntohl ... C Endian Conversion : bit by bit

    0 讨论(0)
  • 2020-11-30 05:25

    I don't know what OS you are running, but you typically cannot "open stdin in binary". You can try things like

    int fd = fdreopen (fileno (stdin), outfname, O_RDONLY | OPEN_O_BINARY);
    

    to try to force it. Then use

    uint32_t opcode;
    read(fd, &opcode, sizeof (opcode));
    

    But I have no actually tried it myself. :)

    0 讨论(0)
  • 2020-11-30 05:37

    fread() suits best for reading binary data.

    Yes, char array is OK, if you are planning to process them bytewise.

    0 讨论(0)
  • 2020-11-30 05:42

    What you need is freopen(). From the manpage:

    If filename is a null pointer, the freopen() function shall attempt to change the mode of the stream to that specified by mode, as if the name of the file currently associated with the stream had been used. In this case, the file descriptor associated with the stream need not be closed if the call to freopen() succeeds. It is implementation-defined which changes of mode are permitted (if any), and under what circumstances.

    Basically, the best you can really do is this:

    freopen(NULL, "rb", stdin);
    

    This will reopen stdin to be the same input stream, but in binary mode. In the normal mode, reading from stdin on Windows will convert \r\n (Windows newline) to the single character ASCII 10. Using the "rb" mode disables this conversion so that you can properly read in binary data.

    freopen() returns a filehandle, but it's the previous value (before we put it in binary mode), so don't use it for anything. After that, use fread() as has been mentioned.

    As to your concerns, however, you may not be reading in "32 bits" but if you use fread() you will be reading in 4 chars (which is the best you can do in C - char is guaranteed to be at least 8 bits but some historical and embedded platforms have 16 bit chars (some even have 18 or worse)). If you use fgets() you will never read in 4 bytes. You will read in at least 3 (depending on whether any of them are newlines), and the 4th byte will be '\0' because C strings are nul-terminated and fgets() nul-terminates what it reads (like a good function). Obviously, this is not what you want, so you should use fread().

    0 讨论(0)
  • 2020-11-30 05:42

    fgets() is all wrong here. It's aimed at human-readable ASCII text terminated by end-of-line characters, not binary data, and won't get you what you need.

    I recently did exactly what you want using the read() call. Unless your program has explicitly closed stdin, for the first argument (the file descriptor), you can use a constant value of 0 for stdin. Or, if you're on a POSIX system (Linux, Mac OS X, or some other modern variant of Unix), you can use STDIN_FILENO.

    0 讨论(0)
  • 2020-11-30 05:42

    I had to piece the answer together from the various comments from the kind people above, so here is a fully-working sample that works - only for Windows, but you can probably translate the windows-specific stuff to your platform.

    #include "stdafx.h"
    #include "stdio.h"
    #include "stdlib.h"
    #include "windows.h"
    #include <io.h>
    #include <fcntl.h>
    
    int main()
    {
        char rbuf[4096];
        char *deffile = "c:\\temp\\outvideo.bin";
        size_t r;
        char *outfilename = deffile;
        FILE *newin;
    
        freopen(NULL, "rb", stdin);
        _setmode(_fileno(stdin), _O_BINARY);
    
        FILE *f = fopen(outfilename, "w+b");
        if (f == NULL)
        {
            printf("unable to open %s\n", outfilename);
            exit(1);
        }
    
        for (;; )
        {
            r = fread(rbuf, 1, sizeof(rbuf), stdin);
            if (r > 0)
            {
                size_t w;
                for (size_t nleft = r; nleft > 0; )
                {
                    w = fwrite(rbuf, 1, nleft, f);
                    if (w == 0)
                    {
                        printf("error: unable to write %d bytes to %s\n", nleft, outfilename);
                        exit(1);
                    }
                    nleft -= w;
                    fflush(f);
                }
            }
            else
            {
                Sleep(10); // wait for more input, but not in a tight loop
            }
        }
    
        return 0;
    }
    
    0 讨论(0)
提交回复
热议问题