Thread: defaulting ifstream variable to standard input

  1. #1
    Registered Luser risby's Avatar
    Join Date
    Jun 2006
    Posts
    72

    defaulting ifstream variable to standard input

    Hi peeps

    Can anyone tell me what must be a fairly standard incantation?

    About a decade ago I wrote
    Code:
        ifstream fin;
    
        if (NULL == inputStream)
        {
            fin.attach(0);
            inputStream = "stdin";
        }
        else
        {
            fin.open(inputStream, ios::in);
        }
    inputStream is NULL unless a filename has been specified on the command line. The attach() function that was available with that compiler allowed me to use this program as part of a pipeline.

    Code:
    who -a | sortByDate
    or
    Code:
    sortByDate uuu.txt
    I haven't really used C++ since then and the attach() function seems to have been an extension that isn't available today. I can't simply do
    Code:
    fin = cin
    can I?
    ===
    Don't grumble about what you can't have;
    be grateful you don't get what you deserve.

  2. #2
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Same as here: http://www.tek-tips.com/viewthread.c...1448313&page=1

    I don't think there is a way to assign cin to an ifstream.
    Maybe you could open the file then pass either the file or cin to a function (which takes an istream& parameter) that does all the reading?

    Something like this:
    Code:
    void ReadStuff( std::istream&  fin );
    
    int main( int argc, char* argv[] )
    {
    ...
        if ( argc > 1 )
       {
          std::ifstream fin( argv[1] );
          ReadStuff( fin );
       }
       else
       {
          ReadStuff( cin );
       }
    ...
    }
    Last edited by cpjust; 02-05-2008 at 03:35 PM.

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Do you need any ifstream specific functionality? You can use an istream reference:
    Code:
    istream& in;
    
    if ( inputStream == NULL )
      in = cin;
    else
      in = ifstream ( inputStream );
    My best code is written with the delete key.

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Prelude View Post
    Do you need any ifstream specific functionality? You can use an istream reference:
    Code:
    istream& in;
    
    if ( inputStream == NULL )
      in = cin;
    else
      in = ifstream ( inputStream );
    Since in is a reference, you need to initialize it when you declare it.
    Also, I don't think you can assign an fstream to an istream like that. Comeau says "error: initial value of reference to non-const must be an lvalue" if I do:
    Code:
    istream& in = ifstream( "file.txt" );

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by Prelude View Post
    Do you need any ifstream specific functionality? You can use an istream reference:
    Code:
    istream& in;
    
    if ( inputStream == NULL )
      in = cin;
    else
      in = ifstream ( inputStream );
    You must mean:
    Code:
    istream& in = ( inputStream == NULL )? cin : ifstream ( inputStream );
    'Cause references can't be assigned.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by King Mir View Post
    You must mean:
    Code:
    istream& in = ( inputStream == NULL )? cin : ifstream ( inputStream );
    'Cause references can't be assigned.
    That's no good either, because ifstream(inputStream) is a temporary so you are creating a reference to a temporary.

    Without using a pointer there is no real elegant solution to this problem. One method is to break all your code out to a separate function and pass the reference to it:

    Code:
    void code(std::istream &input_stream); // actually processing goes here
    
    if(using_cin)
    {
        code(std::cin);
    }
    else
    {
        std::ifstream in(filename);
        code(in);
    }

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Didn't notice that.

    Well you could do this:
    Code:
    ifstream file_stream;
    if(inputStream)
        file_stream.open(inputStream);
    istream& in = inputStream? file_stream: cin;

    The other way is to change the buffer of a file stream to point to standard input. But that's confusing and error prone.
    Last edited by King Mir; 02-06-2008 at 08:09 AM. Reason: Fixed a bug in the code.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by King Mir View Post
    Didn't notice that.

    Well you could do this:
    Code:
    ifstream file_stream;
    if(!inputStream)
        file_stream.open(inputStream);
    istream& in = inputStream? file_stream: cin;
    I forgot about ifstream:pen(). Yes, that would be one way to do it.

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by cpjust View Post
    I don't think there is a way to assign cin to an ifstream.
    There is but it's not worth it.

    Here an link to an example.
    The linked code redirects an output stream to a file, but similar code can be used to redirect an input stream to act as a ifstream.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  10. #10
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by King Mir View Post
    There is but it's not worth it.

    Here an link to an example.
    The linked code redirects an output stream to a file, but similar code can be used to redirect an input stream to act as a ifstream.
    Oh yeah, I think I tried that once, but I gave up since it didn't look too safe.

  11. #11
    Registered Luser risby's Avatar
    Join Date
    Jun 2006
    Posts
    72
    Quote Originally Posted by King Mir View Post
    Code:
    ifstream file_stream;
    if(!inputStream)
        file_stream.open(inputStream);
    istream& in = inputStream? file_stream: cin;
    That looks good. I've tried it and it works fine with stdin but fails to read anything from a file. I'll play around with it though, thanks.
    ===
    Don't grumble about what you can't have;
    be grateful you don't get what you deserve.

  12. #12
    Registered Luser risby's Avatar
    Join Date
    Jun 2006
    Posts
    72
    Quote Originally Posted by cpjust View Post
    Can I just ask why you posted this? It makes me think I've done something wrong.

    And, btw, what has happened to Tek-Tips? It's been down for the last couple of hours.
    ===
    Don't grumble about what you can't have;
    be grateful you don't get what you deserve.

  13. #13
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by risby View Post
    Can I just ask why you posted this? It makes me think I've done something wrong.

    And, btw, what has happened to Tek-Tips? It's been down for the last couple of hours.
    Just in case anyone else has the same question, they can check both places for the answer.
    Tek-Tips goes up & down more than the stock market. Wait a couple hours and it'll usually be back up.

  14. #14
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    Code:
       std::ifstream foo(argv[1]);
       std::istream fin(std::cin.rdbuf());
    
       if(foo)
       {
          fin.rdbuf(foo.rdbuf());
       }
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  15. #15
    Registered Luser risby's Avatar
    Join Date
    Jun 2006
    Posts
    72
    Quote Originally Posted by XSquared View Post
    Code:
       std::ifstream foo(argv[1]);
       std::istream fin(std::cin.rdbuf());
    
       if(foo)
       {
          fin.rdbuf(foo.rdbuf());
       }
    That works. Thanks all.
    ===
    Don't grumble about what you can't have;
    be grateful you don't get what you deserve.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Input class project (again)
    By Elysia in forum C++ Programming
    Replies: 41
    Last Post: 02-13-2009, 10:52 AM
  2. Writing a Variable as a string input to a function
    By gaza2k1 in forum C++ Programming
    Replies: 4
    Last Post: 11-29-2007, 01:04 PM
  3. Outputting to a File Modified Text
    By alpha in forum C++ Programming
    Replies: 8
    Last Post: 11-24-2003, 08:39 PM
  4. creating class, and linking files
    By JCK in forum C++ Programming
    Replies: 12
    Last Post: 12-08-2002, 02:45 PM
  5. Variable Allocation in a simple operating system
    By awkeller in forum C Programming
    Replies: 1
    Last Post: 12-08-2001, 02:26 PM