readsome() on cin

The readsome() unformatted I/P function applied to cin doesn't seem to work properly:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>         /// cin, cout
 
using namespace std;
 
 
void read()
{
    char buf[80] {};
 
    cin.readsome(buf, 3);
 
    if (cin)
    {
        cout << "cin.readsome() successfully read "
             << cin.gcount() << " characters: ";
 
        cout << buf << endl;
 
        cout << "next char: " << (char) cin.peek()
             << endl;
 
        /// discard the character
        cin.ignore();
    }
    else
        cout << "cin.readsome() was unsuccessful" << endl;
}
 
 
int main()
{
	for (int i = 0; i < 3; i++)
       read();
}


https://ideone.com/1XC8YT


Standard I/P:


1234567890



Standard O/P:


cin.readsome() successfully read 0 characters: 
next char: 1
cin.readsome() successfully read 0 characters: 
next char: 2
cin.readsome() successfully read 0 characters: 
next char: 3


My queries:
1) readsome()'s functionality is highly implementation-dependent (according to documentation). Is this the way readsome() is supposed to work with cin or am I doing something wrong?

Thanks
Last edited on
> Is this the way readsome() is supposed to work with cin or am I doing something wrong?

By default, input from std::cin is unbuffered (it needs to coexist peacefully with C stdio).
readsome() requires buffered input.

Make it buffered by doing this right at the outset:
1
2
// http://en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio
std::ios_base::sync_with_stdio(false); // de-link C++ streams from their C counterparts 

and there is a reasonable chance that readsome() would work as expected by this program.
https://ideone.com/AMXKgK
The solution works perfectly.

I wanted to understand one thing, though.

Evidently, synchronization of the standard C++ streams with the standard C streams (which is done by default) causes the standard C++ streams to be unbuffered. Why?

It would appear that synchronization and buffering are mutually exclusive. Is this so and why?

Thanks.
> It would appear that synchronization and buffering are mutually exclusive

For the standard streams, C specifies:
At program startup, three text streams are predefined and need not be opened explicitly — standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.


It may be possible to change the buffering of the standard C streams with std::setbuf / std::setvbuf; however, the C standard states that buffering behaviour is implementation defined. C99, re. buffering:
Support for these characteristics is implementation-defined, and may be affected via the setbuf and setvbuf functions.


Linux libstdc++/libc++: http://coliru.stacked-crooked.com/a/60d66f73673eb2b0
std::setbuf on stdin is effectively ignored.

Microsoft: http://rextester.com/ZZVC16680
Note that in the Microsoft library, even afterstd::setbuf, the buffering of stdin starts only after the actual first input.
So, from your reply, I understand the following 2 points:

1) It's basically because C specifies stdin, stdout and stderr to be unbuffered, that cin, cout and cerr are unbuffered, when synchronized with the former.

2) Otherwise, synchronization and buffering needn't be mutually exclusive.
Honestly, something doesn't quite add up.

Please recall my earlier post:


Evidently, synchronization of the standard C++ streams with the standard C streams (which is done by default) causes the standard C++ streams to be unbuffered. Why?

It would appear that synchronization and buffering are mutually exclusive. Is this so and why?


Borges has affirmed this with his reply.

However, now look at what Stroustrup has to say ["CPL", 4th Ed, pp 1088-1089] :


A call of sync_with_stdio(true) ... guarantees that the iostream and stdio operations share buffers.

A call of sync_with_stdio(false) ... prevents buffer sharing ...


Thus, Stroustrup is saying that synchronization causes buffer sharing, not unbuffering.

Can anyone explain this?

Thanks.

> It's basically because C specifies stdin, stdout and stderr to be unbuffered

C specifies that stdin and stdout are fully buffered if and only if "the stream can be determined not to refer to an interactive device"; and that stderr is never fully buffered.

In almost every implementation, stdout (referring to an interactive device) is line-buffered.
Topic archived. No new replies allowed.