7

I am trying to read a large binary file thought input redirection (stdin) at runtime, and stdin is mandatory.

./a.out < input.bin

So far I have used fgets. But fgets skips blanks and newline. I want to include both. My currentBuffersize could dynamically vary.

FILE * inputFileStream = stdin; 
int currentPos = INIT_BUFFER_SIZE;
int currentBufferSize = 24; // opt
unsigned short int count = 0; // As Max number of packets 30,000/65,536
while (!feof(inputFileStream)) {
    char buf[INIT_BUFFER_SIZE]; // size of byte
    fgets(buf, sizeof(buf), inputFileStream);
    cout<<buf;
    cout<<endl;
}

Thanks in advance.

10
  • 3
    fread is for unprocessed input. fgets as you say does text processing. Don't ignore the return value which is the number of valid records stored to the buffer. Commented Sep 28, 2016 at 20:48
  • 2
    See "stackoverflow.com/questions/7587595/…" Duplicate? Answer there is you can't. Commented Sep 28, 2016 at 20:56
  • 1
    Why are you using C stdio in C++? Commented Sep 28, 2016 at 21:03
  • @DOUGLASO.MOEN Yes you can. First of all, that question is specifically about doing it with cin, so it's not really related to this question, and secondly, the answer there actually tells you how to do it. This question was just a failure to read documentation for stdio / a failure to search Google for "read binary data from stdin". Commented Sep 28, 2016 at 21:04
  • 2
    @JasonC ... thanks, I did not distinguish stdin from std::cin on first read. Commented Sep 28, 2016 at 21:08

1 Answer 1

14

If it were me I would probably do something similar to this:

const std::size_t INIT_BUFFER_SIZE = 1024;

int main()
{
    try
    {
        // on some systems you may need to reopen stdin in binary mode
        // this is supposed to be reasonably portable
        std::freopen(nullptr, "rb", stdin);

        if(std::ferror(stdin))
            throw std::runtime_error(std::strerror(errno));

        std::size_t len;
        std::array<char, INIT_BUFFER_SIZE> buf;

        // somewhere to store the data
        std::vector<char> input;

        // use std::fread and remember to only use as many bytes as are returned
        // according to len
        while((len = std::fread(buf.data(), sizeof(buf[0]), buf.size(), stdin)) > 0)
        {
            // whoopsie
            if(std::ferror(stdin) && !std::feof(stdin))
                throw std::runtime_error(std::strerror(errno));

            // use {buf.data(), buf.data() + len} here
            input.insert(input.end(), buf.data(), buf.data() + len); // append to vector
        }

        // use input vector here
    }
    catch(std::exception const& e)
    {
        std::cerr << e.what() << '\n';
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

Note you may need to re-open stdin in binary mode not sure how portable that is but various documentation suggests is reasonably well supported across systems.

Sign up to request clarification or add additional context in comments.

8 Comments

I have recently started programming in C++ could you explain me this method fread(buf.data(), sizeof(buf[0]), buf.size(), stdin)) ... I understand the this function reads unprocessed filestream - stdin, but I am lost at the first three arguments...
@Jerry Its probably worth reading through the documentation: en.cppreference.com/w/cpp/io/c/fread If you only care about reading bytes then just set the second argument to 1, then the third argument says how many bytes to read. Sometimes people read chunks of bytes at a time so they set the second argument to the number of bytes in each record (chunk). In all cases the number of bytes to read is the multiplication of the sizes in the second and third arguments.
I used sizeof(buf[0]) because, if I change my std::array to contain objects that are larger than char the parameters to std::fread will automatically adjust for that.
oh.. I got it..and fread is supposed to read blanks and newlines too isn't... but for some reason its skipping them..
@Jerry It shouldn't skip them esp if you freopn in binary mode as per my example. If it continues to skip them I suggest you edit your question posting a complete code example that produces the error you are describing.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.