Assign cout or cin to a filehandle

C

Cliff Martin

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;
}
 
P

Pete Becker

Cliff said:
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)
 
C

Cliff Martin

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
 
S

Sylvester Hesp

Cliff Martin said:
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);
}
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Cliff said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top