Assign cout or cin to a filehandle

Discussion in 'C++' started by Cliff Martin, Feb 8, 2007.

  1. Cliff  Martin

    Cliff Martin Guest

    Hi,

    I am writing a simple filter type program that can take input from
    file or stdin, and output to a file or stdout. It would make life much
    easier if I could assign cin to a ifstream object and read it like a
    file and do the same for cout (to an ofstream). Any ideas how I could
    do this? Or perhaps some comments on how I could redo the code to do
    what I want? Simplified code follows:

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    #include <algorithm>

    using std::cout;
    using std::endl;
    using std::string;

    void usage(void);

    int main(int argc, char* argv[]) {
    string fields;

    string line;
    std::ifstream infile;
    std::eek:fstream outfile;
    for (int i=0; i<argc; i++) {
    string option = argv;
    std::transform(option.begin(), option.end(), option.begin(),
    tolower);

    if ((option == "-i") || (option == "--infile"))
    {
    if (argc > i) {
    infile.open(argv[++i]);
    if (infile.fail()) {
    std::cerr << "Could not open file for reading!\n";
    exit(EXIT_FAILURE);
    }
    }
    }
    else if ((option == "-o") || (option == "--outfile")) {
    if (argc > i)
    outfile.open(argv[++i]);
    if (outfile.fail()) {
    std::cerr << "Could not open file for writing!\n";
    exit(EXIT_FAILURE);
    }
    }
    }

    std::vector<string> lines;
    if (infile.is_open()) {
    while(getline(infile, line)) {
    lines.push_back(line);
    }

    infile.close();
    }
    else {
    while(getline(std::cin, line)) {
    lines.push_back(line);
    }
    }

    std::vector<string>::iterator lines_iter;
    const std::vector<string>::iterator lines_end=lines.end();
    if (outfile.is_open()) {
    for(lines_iter=lines.begin(); lines_iter!=lines_end; +
    +lines_iter)
    outfile << *lines_iter << endl;

    outfile.close();
    }
    else {
    for(lines_iter=lines.begin(); lines_iter!=lines_end; +
    +lines_iter)
    cout << *lines_iter << endl;
    }

    return EXIT_SUCCESS;
    }
    Cliff Martin, Feb 8, 2007
    #1
    1. Advertising

  2. Cliff  Martin

    Pete Becker Guest

    Cliff Martin wrote:
    >
    > I am writing a simple filter type program that can take input from
    > file or stdin, and output to a file or stdout. It would make life much
    > easier if I could assign cin to a ifstream object and read it like a
    > file and do the same for cout (to an ofstream). Any ideas how I could
    > do this?


    Nope. But that's not the best approach. The type of the standard input
    stream is a class derived from std::istream, and the types of the
    standard output streams are derived from std::eek:stream. Similarly,
    std::ifstream is derived from std::istream, and std::eek:fstream is derived
    from std::eek:stream. So write your I/O functions to take istreams and
    ostreams by reference, and call them with the appropriate object.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
    Pete Becker, Feb 8, 2007
    #2
    1. Advertising

  3. Cliff  Martin

    Cliff Martin Guest

    > from std::eek:stream. So write your I/O functions to take istreams and
    > ostreams by reference, and call them with the appropriate object.
    >
    > -- Pete


    That worked, thanks. I open the files pass them in to a function as an
    istream or ostream reference. If the filename was not provided for
    either, I pass in std::cout or std::cin.

    so with a function like this:
    process_file(std::istream &infile, std::eek:stream &outfile)

    I can call it like this:

    process_file(ifstream_filehandle, ofstream_filehandle);

    or

    process_file(ifstream_filehandle, std::cout);

    or

    process_file(std::cin, std::cout)

    Just what I was looking for. Thanks again.

    Cliff
    Cliff Martin, Feb 9, 2007
    #3
  4. Cliff  Martin

    Pete Becker Guest

    Cliff Martin wrote:
    >
    > Just what I was looking for. Thanks again.
    >


    That's the power of object-oriented programming.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
    Pete Becker, Feb 9, 2007
    #4
  5. "Cliff Martin" <> wrote in message
    news:...
    > Hi,
    >
    > I am writing a simple filter type program that can take input from
    > file or stdin, and output to a file or stdout. It would make life much
    > easier if I could assign cin to a ifstream object and read it like a
    > file and do the same for cout (to an ofstream). Any ideas how I could
    > do this?


    Pete already showed you the better approach, but it is possible to "assign"
    a stream to another. I used quotation marks because you're not really
    assigning them, rather you're replacing the underlaying stream buffers that
    are responsible for the actual IO of the streams:

    #include <iostream>
    #include <fstream>

    int main()
    {
    // create a new streambuf object that writes to a file
    std::filebuf outFileBuf("myfile.txt", std::ios::eek:ut);

    // set the streambuf object to cout and store the previous streambuf
    std::streambuf * oldBuf = std::cout.rdbuf(&outFileBuf);

    std::cout << "This writes to myfile.txt rather than stdout" <<
    std::endl;

    // restore original streambuf
    std::cout.rdbuf(oldBuf);
    }
    Sylvester Hesp, Feb 9, 2007
    #5
  6. Cliff Martin wrote:

    > I am writing a simple filter type program that can take input from
    > file or stdin, and output to a file or stdout. It would make life much
    > easier if I could assign cin to a ifstream object and read it like a
    > file and do the same for cout (to an ofstream). Any ideas how I could
    > do this? Or perhaps some comments on how I could redo the code to do
    > what I want? Simplified code follows:


    You can use an ofstream and a ifstream. Create each of them without
    arguments and, depending on the situation, open the file or use rdbuf to
    make the underlying stream use the streambuf of cin or cout.

    --
    Salu2
    =?ISO-8859-15?Q?Juli=E1n?= Albo, Feb 9, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. TaiwanNoWhere

    cin and cin.clear() problem

    TaiwanNoWhere, Oct 13, 2003, in forum: C++
    Replies:
    8
    Views:
    4,093
    P.J. Plauger
    Oct 17, 2003
  2. Chris Mantoulidis

    std::cin.ignore() and std::cin.clear()

    Chris Mantoulidis, Jan 6, 2004, in forum: C++
    Replies:
    5
    Views:
    17,138
    Kevin Saff
    Jan 6, 2004
  3. gouki
    Replies:
    3
    Views:
    439
    David Harmon
    Aug 6, 2004
  4. Aleander

    cin and cin.getline()

    Aleander, Mar 6, 2005, in forum: C++
    Replies:
    5
    Views:
    8,666
    Alex Vinokur
    Mar 6, 2005
  5. Fernando
    Replies:
    4
    Views:
    1,650
    Fernando
    Nov 16, 2011
Loading...

Share This Page