Thread: simple I/O question

  1. #1
    Registered User Mortissus's Avatar
    Join Date
    Dec 2004
    Location
    Brazil, Porto Alegre
    Posts
    152

    simple I/O question

    Hi everyone!

    I need this: the user can choose the name of the output file, however, if the file can not be open, the program will automatically use cout. I donīt want to do this with if, because there are many regions in the program that use this output file, the code will become dirty if I use if

    A sample high-level algorithm would be:

    Code:
    out_file.open(user_file);
    if(!out_file){
       out_file = cout;
    }
    
    //use out_file at will
    Thanks any help!

  2. #2
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    I'm afraid I haven't worked with C++-specific stuff in a very long time, so I can only offer a C-style solution, but it'll still work in C++, and the idea might even be applicable to C++ objects.

    In C, a lot of the standard output functions are simply duplicates of file-handling functions with stdout specified as the file pointer. You could have a global variable be a file pointer. Set it equal to stdout if the user-specified file cannot be opened, and then use that file pointer in the file-handling functions.

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    You can redirect output from cout to a file if you successfully open the file. If the file is not open you write to cout as normal.

    Code:
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
        ofstream output("output.txt");
        streambuf* saved_cout = NULL;
    
        // If output is open, make cout actually write to output
        if( output.is_open() )
        {
            saved_cout = cout.rdbuf();  // Save existing cout for later
            cout.rdbuf(output.rdbuf()); // Redirect cout to use file
        }
    
        // This will go to cout if file was not opened, otherwise it is sent to the file
        cout << "Hello World!" << endl;
    
        // Restore cout if it had been redirected
        if( saved_cout ) cout.rdbuf(saved_cout);
    
        // Output message to console per normal cout operations.
        cout << "Goodbye!" << endl;
    
    }
    This may or may not help you out.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User Mortissus's Avatar
    Join Date
    Dec 2004
    Location
    Brazil, Porto Alegre
    Posts
    152
    Thanks for both reply, really good ideas. sean_mackrory your idea is very simple and clean, my fault that I didnīt think this solution . Iīve changed your code hk_mp5kpdw, hope you donīt mind.
    Code:
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
        fstream output("output.txt");
    
        // Presume that the file was correctly open
        ostream out(output.rdbuf());
    
        // If not, redirect do cout
        if( !output )
        {
            out.rdbuf(cout.rdbuf());
        }
    
        // This will go to cout if file was not opened, otherwise it is sent to the file
        out << "Hello World!" << endl;
    
    }

  5. #5
    Registered User
    Join Date
    Mar 2004
    Posts
    494
    that solution still doesnt meet your requirments though. because

    I need this: the user can choose the name of the output file,
    and in the code you have
    Code:
    fstream output("output.txt");
    so the user has no saying on choosing the filename as the file name is coded in the program.

    atleast thats what i assume from your post, correct me if im wrong.
    When no one helps you out. Call google();

  6. #6
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by InvariantLoop
    that solution still doesnt meet your requirments though. because

    ...

    and in the code you have

    ...

    so the user has no saying on choosing the filename as the file name is coded in the program.

    atleast thats what i assume from your post, correct me if im wrong.
    At least for my post, it was just an example of how to redirect output streams. What I posted does not address the issue of a user choosing the name of the file nor was it intended to. I would guess the OP's response was simply more experimentation with the concept of redirection, i.e. playing around with the concept.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  7. #7
    Registered User
    Join Date
    Mar 2004
    Posts
    494
    hk_mp5kpdw yes i know that my reply was towards the orignal poster of this thread, not you hehe.

    im facing exactly the same problem and i have yet to find a solution
    When no one helps you out. Call google();

  8. #8
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Unless I'm totally drunk std::cout is an ostream as well as std::fstream.
    Code:
    void WriteOrWhatever(std::ostream& stream)
    {
       stream << "Stuff!";
    }
    
    void SelectFile(const std::string& filename)
    {
       std::ofstream file(filename.c_str());
    
       if(file.fail())
       {
          WriteOrWhatever(std::cout);
       }
       else
       {
          WriteOrWhatever(file);
          file.close();
       }
    }
    Note that outstream files have very little chance of failing...
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simple Question!!
    By gameuser in forum C++ Programming
    Replies: 2
    Last Post: 06-06-2009, 05:42 PM
  2. Simple question about file I/O.
    By The7thCrest in forum C++ Programming
    Replies: 2
    Last Post: 02-04-2009, 05:15 PM
  3. Simple question about pausing program
    By Noid in forum C Programming
    Replies: 14
    Last Post: 04-02-2005, 09:46 AM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. Overlapped I/O and Completion Port :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 10-30-2002, 05:14 PM