3

cin is an istream object.

It is created in iostream:

      /**
   *  @name Standard Stream Objects
   *
   *  The &lt;iostream&gt; header declares the eight <em>standard stream
   *  objects</em>.  For other declarations, see
   *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/io.html
   *  and the @link iosfwd I/O forward declarations @endlink
   *
   *  They are required by default to cooperate with the global C
   *  library's @c FILE streams, and to be available during program
   *  startup and termination. For more information, see the section of the
   *  manual linked to above.
  */
  //@{
  extern istream cin;       /// Linked to standard input
  extern ostream cout;      /// Linked to standard output
  extern ostream cerr;      /// Linked to standard error (unbuffered)
  extern ostream clog;      /// Linked to standard error (buffered)

#ifdef _GLIBCXX_USE_WCHAR_T
  extern wistream wcin;     /// Linked to standard input
  extern wostream wcout;    /// Linked to standard output
  extern wostream wcerr;    /// Linked to standard error (unbuffered)
  extern wostream wclog;    /// Linked to standard error (buffered)
#endif
  //@}

I tried to create another istream and use it just like cin - it did not work.

#include<iostream>

int main()
{
std::istream dada;
int foo;

dada>>foo;
std::cout<<foo; 

return 0;
}

Because it would not compile. I'm just looking through the library files to understand how cin is linked to my shell but another istream object is not. Can somebody explain? I am interested in the file where the cin get's linked to the STDIN buffer.

Thank you very much.

Thomas E
  • 227
  • 1
  • 10

2 Answers2

4

std::istream is just a facade: it provides useful functions and operators, allowing you to extract numbers, arbitrary amount of characters and other things without fiddling with underlying stream, which is actually just a sequence of characters.

Actual work is done by streambuf object. Streams store a pointer to it and request characters from it when needed. So when you read a number from a stream, stream asks buffer for character until it find non-digit, then transforms digit characters to number.

Now to your question. Standard indeed requires std::cin to be of type std::istream, but it does not say what type its buffer is (aside from that it's derived from std::streambuf). Standard also does not provide such buffer for user to use, so it can be treated as compiler magic.

Only standard way to implement such buffer is to create your own buffer class, derived from streambuf, which will interact with STDIN (or cin, but it would be strange), and pass a pointer to it to istream constructor.

Alternatively, you can use std::cin own buffer:

std::istream my_cin(std::cin.rdbuf());
int x;
my_cin >> x;
Revolver_Ocelot
  • 8,609
  • 3
  • 30
  • 48
  • Or use `std::cin.rdbuf()` –  Jun 12 '16 at 22:35
  • In streambuf there is no `cin` - I don't see where a line of code makes the difference between `cin` and some `std::istream` I create. – Thomas E Jun 12 '16 at 22:50
  • @ThomasE: Note the `extern` in the declaration of `cin`. That means it's actually defined elsewhere, in a different file. And wherever that is, it's being passed a special buffer. Either that, or it is being done in the startup code before `main`. – Benjamin Lindley Jun 12 '16 at 23:11
  • I'd love to see that file, any ideas? – Thomas E Jun 12 '16 at 23:21
  • @ThomasE: Here's the one for the the llvm implementation: https://github.com/llvm-mirror/libcxx/blob/master/src/iostream.cpp -- I don't know where it is in the gcc implementation. – Benjamin Lindley Jun 13 '16 at 00:09
0

cin is implementation of istream object that uses the STDIN buffer.

If you create other object, but without the buffer mapping thing, it won't work.

It is just like you try to use ifstream to read from file but without using the same file name.

It similar to use fscanf(stdin,"%s",p) the stdin is fixed file handle, but it really some wrapper to the STDIN buffer.

SHR
  • 7,940
  • 9
  • 38
  • 57
  • 1
    More accurately, it's not the `istream` implementation, but that it gets passed a custom `streambuf` subclass. –  Jun 12 '16 at 22:28