can I modify ofstream before writting to disk? - c++

std::ofstream ofs;
ofs << "Hello, world!" << endl;
Now I want to modify the contents of ofs to "Hello, money!" before writting to disk?
How can I implement it?

The std::endl IO manipulator will flush the content of the stream buffer, so you will have to change it into a '\n' if you later want to process the stream before its content gets flushed.
Also, under the assumption that the reason you actually want to do this is because you need to manipulate the string which is going to be written after formatting, I shall make you aware of the fact that you can use an std::ostringstream to exploit the functionality of formatted streaming and gather the result into a string, which you can then manipulate and normally write to a file.
If this was obvious information for you and your use case is more complex, then you will have to write your own stream buffer, as pointed out by #MatsPetersson.

Edit: You should make a class derived from filebuf (for the purpose of this discussion myfilebuf and use that to construct an ostream, which is more accurate than the above.
In the myfilebuf you implement sputbackc, and have a statemachine to identify "Hello, World!", and replace it with "Hello, Money!", which probably means buffering a second layer until you know which it is.

Related

What does it mean to open an output file as both input and output?

I see code like this sometimes:
ofstream of("out.txt", ofstream::in | ofstream::out);
Why is it being opened as both input and output? What sense does it make to do that?
Sometimes one needs to read a file, do some processing, then update the original file with some new information. Opening the file for both input and output allows one to do that without closing and re-opening.
It also makes explicit one's intentions with regards to the file.
EDIT: My original answer didn't take into account that the OP's example uses ofstream instead of fstream. So …
Using ofstream with std::in doesn't make any sense. Are there reads performed on the stream? If not, perhaps the code when originally written used an fstream, which was later changed to an ofstream. It's the kind of thing that can creep into a code base that's in maintenance mode.
Since you're using an ofstream, none of the input functions are available to you on the stream. Then opening the file in read-write mode isn't harmful, but it is pointless unless you're going to start hacking about with the underlying stream.
It's probably boilerplate, copy/pasted from some tutorial on the internet without the author actually understanding it.
This means nothing for the actual streams. The std::ios_base::in openmode will simply be ignored. But for the underlying stream buffers, it does mean something to open as both input and output: For example, file stream and string stream buffers allow putback functionality, but it can only be used if the buffers' std::ios_base::openmode specifies output.

What are 'aliased' stream buffers?

What are 'aliased stream buffers`? I encountered the term in a comment on an answer of mine.
I've never heard the term before, but in the thread you cite,
the person who used it also gave an example: two streams which
use the same streambuf.
Of course, just because two streams don't use the same
streambuf, doesn't mean that data written to them doesn't
ultimately end up in the same place; that they don't alias the
same sink, if that is what is meant. There are filtering
streambuf's, which forward the actual sinking and sourcing to
another streambuf, and on most systems, it's possible to open
a file at the system level, and connect a streambuf (or two) to
it.
--
James Kanze
It means an object with different name, for example this:
ostream &lbw = cout;
lbw << "Shahid out" << "Sachin in" << endl; //goes to cout!
What probably was meant in the comment there is this:
ofstream file;
file.rdbuf(cout.rdbuf());
// writes to cout
file << "hello";
So now the check there doesn't work:
if(&file == &cout)
// no, it doesn't

Convert from C++ style printing to my_printf()

C++ purists may want to look away now. You will hate this.
I have been given an open source windows console app that I am merging with a pre-existing, very old, very large windows app of my own. My old program started life as pure C though recently has been tweaked so that it can compile as C++. My program makes extensive use of a my_printf() function which prints text to a window.
The old console app does its printing C++ style via streams (I have never used this type of printing mechanism before).
When converting the console app to work under my system I could manually edit all the lines that do printing so that they use my_printf() instead. But before I embarked on that I thought I'd just check with StackOverflow to see if I was missing a trick. For example I could imagine somehow letting the C++ prints be done via the stream and then somehow scooping the final text somewhere and then calling my_printf() with the result. Might that be possible?
EDIT: please note my knowledge of C++ is extremely limited and I may need to look some things up in order to understand your answers so please use language that facilitates this.
There's indeed a trivial trick. But C++ impurists will hate the fact that C++ has a pure solution ;)
std::ostream is responsible for formatting, but not printing itself. That's handled by std::streambuf. std::cout combines a std::ostream formatter with a std::streambuf-derived object that writes to stdout.
However, you can change the streambuf backing an ostream with ostream::rdbuf(newbuf). As std::cout is just another ostream, you can replace its streambuf too. In this case, you only need to come up with a streambuf-derived class that writes already-formatted output to my_printf(). That should be quite trivial.
You might find string streams useful. For example:
std::ostringstream os;
os << "Print " << whatever << data;
my_printf( "%s", os.str().c_str() );
In case you were feeling adventurous, you could write your own streambuf instead that used my_printf underneath, and inject it into the stream object that is currently used in output statements (e.g. std::cout). Be warned that this latter approach might not be trivial, however it would result in almost no changes to existing codebase.
Subclass std::ostream and make operator << call my_print_f(). You can use internal stringstream in your stream to retrieve string representation of operator << arguments.
Then you'd just have to do find&replace, replacing cout (or whatever stream you directed your output to in the console app) with an instance of your stream class.
Something along these lines might be helpful:
http://www.codeproject.com/KB/debug/debugout.aspx
Should be obvious where the meat of it is, so you can make it print via your own systems, or what have you. In theory, you'd need only search for references to std::cout and replace them with references to your own object.
Overloading the global operator<< is probably what will solve your problem:
#include <iostream>
#include <cstdio>
static int
my_printf (const char* s)
{
printf ("my_printf: %s\n", s);
}
namespace std {
std::ostream& operator<< (std::ostream& out, const char* s)
{
my_printf (s);
return out;
}
}
int
main ()
{
std::cout << "hello, world"; // => my_printf: hello, world
return 0;
}

Internal "Tee" setup

I have inherited some really old VC6.0 code that I am upgrading to VS2008 for building a 64-bit app. One required feature that was implemented long, long ago is overriding std::cout so its output goes simultaneously to a console window and to a file. The implementation depended on the then-current VC98 library implementation of ostream and, of course, is now irretrievably broken with VS2008. It would be reasonable to accumulate all the output until program termination time and then dump it to a file. I got part of the way home by using freopen(), setvbuf(), and ios::sync_with_stdio(), but to my dismay, the internal library does not treat its buffer as a ring buffer; instead when it flushes to the output device it restarts at the beginning, so every flush wipes out all my accumulated output. Converting to a more standard logging function is not desirable, as there are over 1600 usages of "std::cout << " scattered throughout almost 60 files. I have considered overriding ostream's operator<< function, but I'm not sure if that will cover me, since there are global operator<< functions that can't be overridden. (Or can they?)
Any ideas on how to accomplish this?
You could write a custom stream buffer and attach it to cout with cout.rdbuf(). Your custom stream buffer would then tee the data to cout's original stream buffer and to a stream buffer stolen from an appropriate ofstream.
ofstream flog("log.txt");
teebuf tb(flog.rdbuf(), cout.rdbuf());
cout.rdbuf(&tb);
For your teeing stream buffer you can get an inspiration from this page.
You could use the pre-processor:
#define cout MyLogger
to inject new code.

Does setbuf() affect cout?

Yet again, my teacher was unable to answer my question. I knew who may be able to...
So, I've never really learned C. In C++, I would, obviously, use a cout statement all of the time. In a recent assignment, my teacher told us to make sure to put
setbuf( stdout , NULL );
at the top of main() in order to get an unbuffered output, thus allowing us to see the output properly.
My question is this: will this statement affect a cout statement, or simply a printf() statement that I call?
Thanks in advance!
By default, iostreams and stdio are synchronised. Reference.
This doesn't mean that manually adjusting the stdio buffering is a good idea, though! You may wish to utilise std::endl or std::flush (from <ostream>), which may help you. e.g.,
std::cout << "Hello, world!" << std::endl;
or
std::cout << "Hello, world!\n" << std::flush;
Both of these do the same thing. (std::endl = print endline, then flush.)
By default, if stdout or cout is printing to a console, the output is line buffered. This means that every newline that is printed will flush the output. You can explicitly call flush() whenever you want to override the behavior just in case say, the output is going to be redirected to a file and you want to use tail -f and need certain outputs in realtime.
As Chris said, sync_with_stdio should tie the unbuffered stdout with an unbuffered cout (by default), but if all you are doing is using cout, instead of using setbuf on stdout, a better option is to use pubsetbuf on the pointer returned by rdbuf. ie:
// make cout unbuffered
std::cout.rdbuf()->pubsetbuf(0, 0);
Another function that may be interesting to look at is tie.
Usually, when it's important to see the output immediately, we're talking about complex highly-reliable financial routine that must log a transaction all the way to hard drive before actually sending it to counterparty. Or, (much more common case) we want to see debug messages even when the program is crashing.
Since you're studying, I'll assume you're dealing with the second case. In that case, my advice would be to use stderr rather than stdout. It is unbuffered by default, and you can redirect it separately from stdout, putting your output in one place and your logging in another.