I'm kind of confused by ofstream.
ofstream inherited from ostream. And it
also inherited method "operator<<" from
ostream.
ofstream x;
x << "hello world" << endl;
//cout << "hello world" << endl;
system("pause");
return 0;
The above code clip is trying to use an object of ofsream
to output "hello world" to the terminal just as cout did.
The above code clip can compile but shows nothing.
Why does it happen?
Thanks,
ofstream is an abstraction for a file object. In order to be able to create a file, you need to pass in the file's name. If you don't a default ofstream object is created (which is why it compiles). By itself, such an object isn't of much use. Try:
ofstream x( "out.txt" );
x << "hello world" << endl;
...
It's been a long time, but IIRC of stream is an output_file-stream which streams data into an opened file. For an ofstream object to actually print to the terminal you would have to make it open "/dev/console" or something similar. A plain instance of ofstream probably doesnt open /dev/console b/c you already have cout available.
http://en.wikipedia.org/wiki/Input/output_%28C%2B%2B%29
<iostream> contains the definition of basic_iostream class template,
which implements formatted input and output
<fstream> contains the definitions of basic_ifstream, basic_ofstream and
basic_fstream class templates which implement formatted input, output and input/output
on file streams.
Related
I just started learning C++, and I saw some function in C++ primer like that:
double total_receipt(ostream &os)const{...}
then I try to find the address of cout by using this code: "cout << &cout << endl;"
and that's no difference between ostream &os and direct use cout.
So why not just use cout instead of ostream &os? Or maybe it's just a "good" habit?
First notice:
cout is an object (check these docs)
ostream is a class (check these docs)
When you declare a method, you need to use the class names for the parameters, so if your class uses an "output stream" (that's what ostream means) then you declare your function like:
double total_receipt(ostream &os)
You can't create the function like this:
double total_receipt(cout) // doesn't work
Now, if your question is about what is the difference between declaring the total_receipt function like this:
double total_receipt(ostream &os) {
os << "hello world" << std::endl;
}
or like this:
double total_receipt() {
std::cout << "hello world" << std::endl;
}
That's up to you. Usually, we use the first one as that allows to invoke the function with other things besides cout, like:
ofstream out_file("my_file.txt");
total_receipt(out_file);
So, you can pass to that function any object of classes derived from ostream, like ofstream in the example. This means, your function can print to a file, besides printing to the terminal, so you add more functionality if you need it.
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;
}
I'm creating two functions to save and load a object into the program.
The save function aparently saves the object successfully:
void Game::SaveGame()
{
std::string filename = "saves/miner-save-" + currentDate() + ".gem";
std::ofstream outfile;
outfile.open(filename.c_str(), std::ios::binary);
outfile.write((char *)(&myGame), sizeof(Game));
if (outfile.fail())
std::cout << "write failed" << std::endl;
outfile.close();
std::cout << myGame->myMiner->getX(); //debug purposes : prints 25
}
The problem seems to be in the load function, because the value returned from a integer of the object that is read is incorrect.
void Game::LoadGame()
{
..some code..
std::string filename = GetLoadFilename(nameID); //works
std::ifstream infile;
infile.open(filename, std::ios::binary);
infile.read((char *)&myGame, sizeof(Game));
if (infile.fail())
{
std::cout << "read failed" << std::endl;
}
std::cout << myGame->myMiner->getX(); //debug purposes : prints -842150451
Play(myGame->myMiner->getX(), myGame->myMiner->getY());
}
Class Game:
class Game {
Game *myGame;
Miner *myMiner;
BlockTypes *myBlockTypes;
//Block* myBlocks[10000];
Consola *myConsole;
Mine *myMine;
int linhas, colunas;
int _currentStatus;
public:
..some functions such as load & save
};
When loading, the "read failed" message is always shown, whats wrong ?
Writing a struct with pointers writes the value of the pointers, not the value of the pointed objects.
You need to look into serialization. Serialization is a way to structure data onto a continuous unstructured medium like a hard drive. ie, how structure your info into a line of bits so you'll be able to reconstruct your objects from that same line of bits. the previously linked boost library is an option, but there is also XML, JSON and other solutions that you should check out.
The general way is to use "infile >> myGame". In the Game class, define operator<< and operator>> to override the defaults with versions customized for your Game class.
These functions generally have a list of >> or << for each member of the class (which is the default if you don't define the operators). But you need to make some decisions and write some code for the pointer type members. The locations of objects in memory will move from run to run, so you can't just save and load pointer values. For instance, maybe in Game::operator<< you need to call << on myMine to dump it (deep copy). But maybe Miner is a pointer into an array that is saved and loaded separately, so Game::operator<< saves a miner id number or name string and Game operator>> uses the saved data to look up the up the Miner to get the pointer.
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'm writing a small/beta testing program that will be put to use in my much bigger program for a project. It requests the user for an input file name (IE data.txt) and creates an output file named filename.out (IE data.out). I've tried a simple outFile << "text here"; to try it out but it doesn't create output file. I'm sure I'm messing something simple here but I can't figure out what.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
//Global variables
ifstream inFile;
ofstream outFile;
void main()
{
// Requests user for input filename
string inputFile;
cout << "Enter File Name: ";
cin >> inputFile;
string outputFile = inputFile.substr(0, inputFile.find_last_of('.')) + ".out";
// Opens both inputFile and outputFile
inFile.open(inputFile.c_str(), ios::in);
outFile.open(outputFile.c_str(), ios::in);
// Checks for input file
if (!inFile)
{
cout << "Unable to open file" << endl;
exit(1);
}
outFile << "Hello world!";
inFile.close();
outFile.close();
}
Because you're trying to open the file for reading:
outFile.open(outputFile.c_str(), ios::in);
Use ios::out instead.
Why did you make these streams global variables rather than local ones? In C++, it's generally preferred to construct objects as late as possible. If you do this, you have all information available to open the streams right in the constructor, which can take the same arguments as the open() member function.
One difference between std::ifstream and std::ofstream is that their open() member functions and constructors apply a different default opening mode. It's in for std::ifstream and out for std::ofstream. You can always override these, but that would somewhat defeat the reason for using those streams in the first place. You could use std::fstream, too. For that you would always have to supply the opening modes. If you're using std::ifstream and std::ofstream, just skip the opening modes. Here's how this is looks when using the constructors instead of the open() member functions (it looks pretty much the same with the latter):
std::ifstream inFile(inputFile.c_str());
std::ofstream outFile(outputFile.c_str());
It's int main(), even if some compilers allow void.
I have strong objections to using directives. But these objections are not as widely shared as the other opinions listed in this answer.