Thread: returning a stream from a function

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    62

    returning a stream from a function

    I'm trying to make a class that takes the argv parameters and creates various ifstreams and ofstreams with it (and also redirects cout, clog and cerr if the right commands are given in the argv).

    But I have not been abble to sucessfully make my functions return the stream (I don't really have a lot of experience with streams).

    So one example of this would be this function:
    Code:
    ifstream& ccinterface::no_cc_msg()   {
    //if no commands were given explains how to use console commands
    // and asks the user for the input file
        help();
        cout<<"Alternatively you may define the input file here (all other specifications"<<endl
            <<"will be regarded has defaulf if you have not defined them):"<<endl;
        string input_str;
        cin>>input_str;
        ifstream input(input_str.c_str());
        return input;
    }
    that I would then like to store the result in my input variable there:
    Code:
    //(...constructor...)
    if (argc==1) input(no_cc_msg());
            
            
        }
    private:
        ifstream input;
        void help();
        ifstream& no_cc_msg();
    //(...)
    I'm guessing my problem is on how i'm trying to assign the data to the stream but I've tried a few ways and haven't figured out the correct way to do it.

    tks in advance for any help i get

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by killme
    So one example of this would be this function:
    The problem here is that input is a local variable. When you return it, you have a problem, because once control returns from the function, the stream object is destroyed, yet you are returning a reference to it. Consequently, the caller would have a reference to an object that no longer exists, which is a Bad Thing.

    Now, if input is going to be a member variable instead, then one solution is to get rid of that local variable (which you obviously will do in such a case) and use the open member function of the stream instead. Then, no_cc_msg will have void return type. Note that objects of this class will be not be copyable since input stream objects are not copyable, so you might want to declare the copy constructor and copy assignment operator as private to make that clear.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2011
    Posts
    62
    thank you, after dabbling about for a bit I managed to come up with this:
    Code:
    void ccinterface::no_cc_msg(ifstream& input)   {
    //if no commands were given explains how to use console commands
    // and asks the user for the input file
        help();
        cout<<"Alternatively you may define the input file here (all other specifications"<<endl
            <<"will be regarded has defaulf if you have not defined them):"<<endl;
        string input_str;
        cin>>input_str;
        input.open(input_str.c_str());
    }
    that seems to work as I wanted it to, thank you very much.

  4. #4
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    If you're using C++11, you could return a smart pointer to a new allocated stream object.

    Code:
    std::unique_ptr< std::istream > makeStream( /* various argument here ....... */ )
    {
        return std::move( std::unique_ptr< std::istream >( new std::ifstream( /* input file path, etc. */ ) ) );
    }
    P.S. But your solution is probably better since it involves no superfluous mucking around with the freestore.
    Last edited by antred; 03-20-2013 at 12:01 PM.

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by laserlight View Post
    input stream objects are not copyable
    They can't be copied, but under C++11, can they be moved?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by brewbuck View Post
    They can't be copied, but under C++11, can they be moved?
    Yes:
    Code:
    #include <fstream>
    #include <string>
    #include <iostream>
    
    std::ifstream test() { return std::ifstream("C:\\test.txt"); }
    
    int main ()
    {
    	std::ifstream test2 = test();
    	std::string txt;
    	std::getline(test2, txt);
    	std::cout << txt << std::endl;
    }
    To bring the point home, if you add

    std::ifstream test3 = test2;

    then you will get a compile error because you cannot copy the object.
    Also, antred, your solution is silly. You don't need to move a unique_ptr. Furthermore, it is also silly to use a smart pointer in the first case since the streams are movable.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 09-06-2011, 02:59 PM
  2. returning false as a stream?
    By shiverbug in forum C++ Programming
    Replies: 2
    Last Post: 12-08-2009, 10:53 PM
  3. Recursion: base case returning 1, function returning 0
    By yougene in forum C Programming
    Replies: 5
    Last Post: 09-07-2007, 05:38 PM
  4. Stream as return function
    By AngKar in forum C# Programming
    Replies: 4
    Last Post: 05-24-2006, 10:18 PM
  5. Stream function question
    By 3kgt in forum C++ Programming
    Replies: 1
    Last Post: 03-04-2003, 06:30 PM