On 25.01.2017 20:29, Christiano wrote:
> I come from the C language, see the following example:
>
> // {======= get.c ============
> #include <stdio.h>
>
> int main(void)
> {
> char c;
> char d;
>
> c = getchar();
> d = getchar();
>
> putchar(c);
>
> printf("\n");
>
> putchar(d);
>
> printf("\n");
>
>
> return 0;
> }
> // }======= end get.c ========
>
> Running (comments using notation ## comments ##):
> debian@debian:~/principles$ gcc get.c -o get
> debian@debian:~/principles$ ./get
> ##First I press Ctrl+D##
> ##Ctrl+D again##
> �
> �
> debian@debian:~/principles$
Yep, the C FILE* streams do not have EOF as a state, they just report
EOF when they read in zero bytes – which is what happens when you press
Ctrl+D without having typed anything on the line, there is nothing, so
the read returns an empty sequence of bytes.
At one time long ago this was used in a “readslow” program to follow the
thinking of a famous chess program.
Wait let me google that. OK found something about it, not the chess
tournament thing, but it was mentioned in the old classic “The UNIX
Programming Environment” by Kernighan & Pike:
[TUPE]
> It is quite legal for several processes to be accessing the same file at the
> same time; indeed, one process can be writing while another is reading. If this
> isn’t what you wanted, it can be disconcerting, but it’s sometimes useful. Even
> though one call to read returns 0 and thus signals end of file, if more data is
> written on that file, a subsequent read will find more bytes available. This
> observation is the basis of a program called reads low, which continues to
> read its input, regardless of whether it got an end of file or not. reads low is
> handy for watching the progress of a program:
>
> $ slowprog >temp &
>
> 5213 Process-id
>
> $ readslow <temp I grep something
>
> In other words, a slow program produces output in a file; readslow, perhaps
> in collaboration with some other program, watches the data accumulate.
>
> Structurally, readslow is identical to cat except that it loops instead of
> quitting when it encounters the current end of the input. It has to use low-
> level I/O because the standard library routines continue to report EOF after the
> first end of file.
>
> /* readslow: keep reading, waiting for more */
>
> #define SIZE 512 /* arbitrary */
>
> main ( )
> {
> char buf [SIZE] ;
> int n;
>
> for (;;) {
> while ( (n = read( 0 , buf, sizeof buf)) > 0)
> write ( 1 , buf , n) ;
> sleep( 10 ) ;
> }
> }
>
> The function sleep causes the program to be suspended for the specified
> number of seconds; it is described in sleep(3). We don’t want readslow to
> bang away at the file continuously looking for more data; that would be too
> costly in CPU time. Thus this version of readslow copies its input up to the
> end of file, sleeps a while, then tries again. If more data arrives while it is
> asleep, it will be read by the next read.
[/TUPE]
Continuing with your posting:
On 25.01.2017 20:29, Christiano wrote:
> Ok, Let's see something equivalent in C ++.
>
> // {=========== get++.cpp ===========
> #include <iostream>
> using namespace std;
>
> int main(void)
> {
> char c;
> char v;
>
> cin >> c;
> cin >> v;
>
> cout << c;
>
> cout << endl;
>
> cout << v;
>
> cout << endl;
>
> return 0;
> }
> // }=========== end get++.cpp ======
>
> There is a difference in behavior here.
Yes, them dang iostreams are /stateful/. Once a stream gets into an
error state, which is a kind of “ignore all attempted operations” mode,
you have to clear it in order to continue.
In passing, `f(void)` is a C-ism. In C the `void` there ensures that the
function is declared as taking no arguments, as opposed to an arbitrary
number of arguments with just `f()`. But in C++ `f()` says directly that
it takes no arguments, there's no need for `f(void)`.
Yes. But it's a different issue. The `keep_window_open` function does
clear the stream error state, via a call to `clear`. But it fails to
empty the input buffer, where characters from the failed read still
linger. It could empty the input buffer with a call to `ignore`.
Check whether this bug is already in the book's errata list. If it isn't
then report it to Bjarne.
> Is this behavior normal?
Yes, it's by design.
But note that the `keep_window_open` issue is not the same as the end of
file state you encountered earlier.
For the first issue, about EOF, try out the following program:
#include <iostream>
#include <string>
using namespace std;
auto main()
-> int
{
double x;
cout << "? "; cin >> x;
if( cin.fail() )
{
cout << "Failed. This was left in input buffer: `";
cin.clear();
string s; getline( cin, s );
cout << s << "`." << endl;
}
else
{
cout << "Oh, the number " << x << "! Thanks! :)" << endl;
Cheers & hth.,
- Alf