7

I did a simple test with C++ code and using the helper tool pv(pipe viewer). The code is:

#include <iostream>
#include <array>

int main() {
    std::array<char,4096> buffer;
    while( true ) {
        std::cin.readsome(buffer.data(),4096);
    }
}

I execute with:

pv /dev/urandom | ./a.out

Through pv, I notice that readsome never reads anything. What am I missing?

André Puel
  • 8,741
  • 9
  • 52
  • 83

3 Answers3

3

Please see cppreference, especially under "Notes".

The behavior of this function is highly implementation-specific. For example, when used with std::ifstream, some library implementations fill the underlying filebuf with data as soon as the file is opened (and readsome() on such implementations reads data, potentially, but not necessarily, the entire file), while other implementations only read from file when an actual input operation is requested (and readsome() issued after file opening never extracts any characters). Likewise, a call to std::cin.readsome() may return all pending unprocessed console input, or may always return zero and extract no characters.

However, if I try this with:

std::cin >> buffer.data();

Then I can extract the console input. In order to get the behavior you are seeking, I would use std::istream::get(), and check the eof and fail bits in your while loop.

David G
  • 94,763
  • 41
  • 167
  • 253
kwierman
  • 441
  • 4
  • 11
  • You don't want to check `eofbit` and `failbit`, you want to check `std::cin.fail()`, or more idiomatically, simply use `std::cin` as if it were a boolean. (The `eofbit` can be set even after a successful input, and `failbit` isn't sufficient for failing, you also need `badbit`.) – James Kanze Jul 11 '14 at 15:32
  • 1
    I tried putting a single std::cin.get() before the readsome, still, readsome reads nothing. I cant understand when will readsome give me something. – André Puel Jul 11 '14 at 16:34
0

readsome() terminates when its buffer is exhausted, in order to avoid delays. If you don't already have data waiting for the call by the time you execute it, it won't read anything. It won't wait for you.

Logicrat
  • 4,438
  • 16
  • 22
0

For anyone facing this issue:

The issue occurs because the std streams such as cin and cout are not buffered by default, to allow you to use functions from cstdio such as printf() alongside objects from iostream such as cout. You can enable buffering as follows:

std::ios_base::sync_with_stdio(false);

As for the OP's code and also as an example of using readsome(), you should try using readsome() as follows:

#include <iostream>
#include <string>

using namespace std;
int main () {
    std::ios_base::sync_with_stdio(false);
    char* s = new char[10];
    string str;
    bool yn;
    int num;
    cout << "Do you want to readsome? (0/1): ";
    cin >> yn;
    cout << "Feed me: ";
    cin >> num;
    if(yn) cin.readsome(s, 10);
    cout << "You fed me: ";
    cout << num;
    if(yn) cout << "\nThe leftovers are: " << s;
    return 0;
}

Example run:

Do you want to readsome? (0/1): 1
Feed me: 12abc
You fed me: 12
The leftovers are: abc

In the unlikely event this code fails to run for you (make sure you are not giving EOF or blank space input, cin.fail() and cin.bad() are unlikely but you can check them), it may be for the reasons kwierman mentions.