What does the parameter in a class function ostream& outs mean?
e.g
void BankAccout::output(ostream& outs){
outs.setf(ios::fixed);
outs.setf(ios::showpoint);
outs.precision(2);
outs<<"account balance $"<<balance<<endl;
outs<<"Interest rate"<<interest_rate<<"%"<<endl;
}
and why is it that for outputing information onto ouput,it no longer uses cout,but now uses outs?
Make yourself familiar with streams: http://www.cplusplus.com/reference/iolibrary/
Basically ostreams are streams to write into, that output the data somewhere. cout is also an ostream. But you can also open a file as an ostream. So this function lets you decide where the data should be written to. If you want the data written in the terminal you pass cout as the argument. If you want it in a file, you open a file as an ostream and pass that to the function instead.
Just for example:
int main(void)
{
BankAccount *ba = new BankAccount();
ba->output(cout); //prints to terminal
std::ofstream ofile; //ofstream is derived from ostream
ofile.open("test.txt");
ba->output(ofile); //will output to the file "test.txt"
delete ba;
return 0;
}
Related
I am trying to overload both cout from iostream and fout from fstream
ostream& operator<<(ostream& cout, const Object& obj);
ofstream& operator<<(ofstream& fout, const Object& obj);
I want the first function to work with the console so have text for the user while I want the second function to only output the value of the variables onto a file.
However, in
void save_data(const Object& obj)
{
fstream fout("DataBase.txt", ios::out);
if (fout.is_open())
{
fout << obj;
fout.close();
}
else
cout << "DataBase.txt could not be saved!" << endl;
}
I have text that I used to guide the user inside my function that overloads cout in my file.
std::fstream inherits from std::iostream, which in turn inherits from std::ostream. There's no std::ofstream in that chain, making that overload an unsuitable candidate.
One way to fix this is to use std::ofstream at the callsite instead of std::fstream. You can also add an overload for std::fstream. However, be aware that std::ostream is not necessarily the console; that's a guarantee you have to provide yourself from the rest of the code. For example, a std::ofstream could be upcast to std::ostream and then used to print an Object and your overload set would assume this stream is for the console. It might be hard to ensure the rest of your code provides that guarantee. In addition, robust detection of a console is going to be platform-dependent with its own answers elsewhere on the site (e.g., for Windows).
One way that existing programs handle this requirement is to have an explicit "interactive" option on the command line. For example, git commands use --interactive and sometimes -i for this purpose. This way, the user asks for the extra guiding output and there's no clever detection trickery required.
Thanks to the help from #chris I was able to figure out what the real problem was. Normally one doesn't need to overload based on the base and derived I/O stream types. There's usually a polymorphic way to do what you want. In this case you can check if the stream being written to is std::cout and construct a new stream with a buffer to write to it.
std::ostream& operator<<(std::ostream& os, Obj const& obj) {
std::ostream o(nullptr);
if (&os == &std::cout) {
o.rdbuf(std::cout.rdbuf());
}
o << "hello\n";
return os;
}
Writing to o will do nothing if the buffer is a null pointer. This will allow you to write your console output guides for the user without separating both implementations.
If you would still like to split the implementations, create two functions and call the appropriate one when the above if condition is true and false.
std::ostream& write_with_console_o(std::ostream&);
std::ostream& write_with_file_o(std::ostream&);
std::ostream& operator<<(std::ostream& os, Obj const& obj) {
if (&os == &std::cout) {
return write_with_console_o(os);
}
return write_with_file_o(os);
}
I have a main function that prints a sudoku game to the console as I play. I call a print board method which outputs the board along with a 2D array with the numbers. I've been modifying the game to output to the file after every cout:
cout << "puzzle created" << endl;
output << "puzzle created" << endl;
Then the problem is that there is an error when I try the same with a method:
sudoku.printBoard(); //method to print board to console
I can't simply say:
output << sudoku.printBoard();
and I can't say:
output << "number";
in the method in the board.cpp file either.
Does anyone know any way around this?
This is the problem with print() member functions, and the reason you shouldn't write them. At least, not like this. You've locked yourself into printing to stdout, and now that you want to print somewhere else instead, you're stuck.
Instead, have a function that prints where you tell it to. This may be stdout or a file or whatever.
The function will be declared like this:
void printBoard(std::ostream& os);
and inside its definition, you will use os rather than std::cout.
Then your code will look like this:
sudoku.printBoard(std::cout);
sudoku.printBoard(output);
It works because both std::cout and output are of types that derive from std::ostream.
If you need the cout variant a lot, and you don't want to provide the argument every time because it's getting messy, simply provide an overload:
void printBoard()
{
printBoard(std::cout);
}
Now you can still write:
sudoku.printBoard();
Whether this is more or less confusing for developers on your project is for you to decide.
If you don't have other things to print, so that this is the only function of its kind within the type of sudoku, a more idiomatic approach would be to create an operator<< for that type:
std::ostream& operator<<(std::ostream& os, const SudokuBoard& board)
{
board.printBoard(os);
return os;
}
Now you can use it like this:
std::cout << sudoku;
output << sudoku;
Make a class that takes two ostreams in the constructor. One of these can be std::cout. Store these in the class as references.
Create output stream operators (<<) and use those to write to the two streams.
To use this in other classes pass it as a reference in their constructor (look up dependency injection).
Pass ofstream as a reference to your funtion or simply return string from your function and print it in main() or callee function.
In 2nd case you go like this
string f()
{
ostringstream os;
os<<"whatever I want to print in output";
....
...
return os.str();
}
int main() or //womain() from wherever you call
{
output<<f()<<endl;
}
My code has an ostream object that is accumulated by various modules and ultimately displayed to the console. I'd like ALSO to write this ostreamobject to a file, but do I have to rewrite all of that code using an ofstream object instead, or is there a way to convert one to the other (perhaps via a stringstream?)
For example, many of my existing functions look like
ostream& ClassObject::output(ostream& os) const
{
os << "Details";
return os;
}
Can I call this function with an ofstream object as the argument and have that ofstream object accumulate information instead?
Yes, you can. That's the point in the OO concept called subtype polymorphism. Since ofstream derives from ostream, every instance of ofstream is at the same time an instance of ostream too (conceptually). So you can use it wherever an instance of ostream is expected.
ofstream derived from ostream so
Just add some code in main.cpp
#include "ClassObject"
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
ClassObject ob;
cout << ob; // print info to console window
// save info to .txt file
ofstream fileout;
fileout.open("filename.txt", ios::app);
fileout << ob;
fileout.close();
return 0;
}
I am working on a C++ code and I wish to do the following:
In the code there is a new type, T, there is a method defined on T that prints some information to a type FILE* variable.
I would like to do some work on this string inside of the program, so I would like to have a variable of type string (or even char*) that will contain what is printed to the screen (if I give the printing function stdout as the File*).
How can I do this ? maybe I can create some FILE* variable and then create (somehow) a string/char* variable with the information that is stored in that File* variable we created ?
Any help is appreciated!
POSIX 1.2008 fmemopen, open_memstream functions create a FILE* pointer which writes to (and/or reads from) memory.
If it does not work for your platform (and there is no other way to hook into FILE *), then you're out of luck.
The next thing I'd try is creating an anonymous pipe, (POSIX pipe, Windows CreatePipe), wrapping its writing side into FILE * (POSIX fdopen, plus Windows _open_osfhandle to get a CRT fd from HANDLE). Here you have to ensure that the pipe's buffer size is enough, or to spawn a thread for reading the pipe. Don't forget to fflush the writing side after the method is done (or use setbuf to disable buffering).
There are several platform-independent ways to do it.
In C++ you can use stringstream(http://www.cplusplus.com/reference/sstream/stringstream/), which has many << operator overloads. So if you pass a reference to ostream& (not oFstream) to the output method, you can easily switch between files, stadard output stream and string outputs, because all this streams are inherited from ostream. Then you can get std::string object from stringstream and get C-string from it if you need.
Code example:
Output function (or method, then you don't need the second argument from the example):
void PrintMyObjectToSomeStream(std::ostream& stream, const MyClass& obj)
{
stream << obj.pubField1;
stream << obj.pubField2;
stream << obj.GetPrivField1();
stream << "string literal";
stream << obj.GetPrivField2();
}
Usage:
MyClass obj1;
std::ofsstream ofs;
std::stringstream sstr;
//...open file for ofs, check if it is opened and so on...
//...use obj1, fill it's member fields with actual information...
PrintMyObjectToSomeStream(obj1,std::cout);//print to console
PrintMyObjectToSomeStream(obj1,sstr);//print to stringstream
PrintMyObjectToSomeStream(obj1,ofs);//print to file
std::string str1=sstr.str();//get std::string from stringstream
char* sptr1=sstr.str().c_str();//get pointer to C-string from stringstream
Or you can overload operator<<:
std::ostream& operator<<(std::ostream& stream, const MyClass& obj)
{
stream << obj1.pubField;
//...and so on
return stream;
}
then you can use it in this way:
MyClass obj2;
int foo=100500;
std::stringstream sstr2;
std::ofstream ofs;//don't forget to open it
//print to stringstream
sstr2 << obj2 << foo << "string lineral followed by int\n";
//here you can get std::string or char* as like as in previous example
//print to file in the same way
ofs << obj2 << foo << "string lineral followed by int\n";
Using FILE is more C than C++ but you can think how to switch between fpirntf and sprintf or use Anton's answer.
I'm working on a homework project for a virtual rolodex that has called for a main class, a rolodex class, and a card class. To output the contents of all of the "cards" to the console, the assignment says that main() should call a show(...) function in the rolodex class, passing it an ostream and show(...) then iterates over the cards, calling each of their showCard() functions. The actual showing is done by the card objects' showCard() function, showing on the provided ostream.
What I don't understand is why an ostream would/should be passed anywhere. Seems like the assignment is calling for something like this:
main() {
Rolodex myRolodex;
ostream myStream;
myRolodex.show(myStream);
}
void Rolodex::show(ostream& theStream) {
//for each card 'i' in the Rolodex...
myCard[i].show(theStream);
}
void Card::show(ostream& theStream) {
theStream << "output some stuff" << endl;
}
instead of something like this:
main() {
Rolodex myRolodex;
myRolodex.show(); //no ostream passed
}
void Rolodex::show() {
//for each card 'i' in the Rolodex...
myCard[i].show();//no ostream passed
}
void Card::show() {
cout << "output some stuff" << endl;
}
Am I either misunderstanding the use of ostream as a parameter or missing some other obvious reason to pass an ostream down the stream like that?
What I don't understand is why an ostream would/should be passed anywhere.
This is often used for things like testing. Say you want console output normally, so you'd pass around a reference to std::cout. But sometimes you want to do testing, e.g. unit or acceptance testing, and you want to store the output in memory for that. You could use std::stringstream for this, and the function you're working with is none the wiser.
That's one specific case -- but in general any place where you'd want to change where the data source or sink could be coming from / going to, you can do that by passing a stream around.
For example, the following would print your rolodex to the console:
int main()
{
Rolodex myRolodex;
myRolodex.show(std::cout);
}
... but if tomorrow you wanted to write to a file instead, you can do that without affecting the code inside Rolodex at all:
int main()
{
Rolodex myRolodex;
std::ofstream file("This\\Is\\The\\Path\\To\\The\\File.txt");
myRolodex.show(file); // Outputs the result to the file,
// rather than to the console.
}
I would just overload the << operator:
class Card{
public:
friend ostream& operator<<(ostream& os, const Card& s);
};
ostream& operator<<(ostream& os, const Card& s){
os << "Print stuff";
return os;
}
And you could overload in the Rolodex as well to just iterate over the cards.