just want to know whether there is a possible data loss? - c++

I have written a piece of code which writes either to console or to a file depending upon the boolean value set by user.
The code looks like this.
#include <iostream>
#include <fstream>
int main()
{
bool bDump;
std::cout<<"bDump bool"<<std::endl;
std::cin>>bDump;
std::ostream* osPtr;
std::ofstream files;
if(bDump)
{
files.open("dump.txt");
osPtr = &files;
}
else
{
osPtr = &std::cout;
}
std::ostream& stream = *osPtr;
stream<<"hello";
if(bDump)
{
files.close();
}
return 0;
}
Here I am creating a std::ostream pointer and depending upon boolean value I am assinging address of either an ofstream object or std::cout. My only concern here whether the file operation like open or close are done properly or not. As I am new to c++ please help me out. Also point out if any bad programming practice is being followed here.

Its correct and works.
The main thing I would do differently is not to explicitly call close() as this is done automatically by the destructor.
You can simplify your code slightly (and get rid of the pointer) with the ternary operator;
#include <iostream>
#include <fstream>
int main()
{
bool bDump;
std::cout << "bDump bool"<<std::endl;
std::cin >> bDump;
std::ofstream files;
std::ostream& stream = (bDump) ? (files.open("dump.txt"), files)
: std::cout;
stream<<"hello";
}

There's no potential leak. However, if an exception is thrown by
stream<<"hello";
then
files.close();
will never be called, but for your specific example of code there's no concern. ofstream's destructor happens to call close() for you.

You did everything fine, but there is no need for the close() at the end, because in C++ we rely on destructors to clean up for us, and std::ofstream has one which closes the file automatically.
You can also omit the return 0; statement at the bottom of main() in C++: 0 (success, really) will be returned by default.

Related

Is the C++ ostream at the start of a line?

In C++, how do I detect if my std::ostream os is at the start of a line, in other words (I think) the most recent thing written to os is either os<<'\n' or os<<std::endl(), or else nothing has yet been written to os?
At first glance, this sounds unnecessary, because I can just keep track of the state myself. But a common scenario is the following, where keeping track would involve altering every os<<thing statement which could possibly be called from the try block, in a very unnatural way.
try {
do_something_which_writes_to(std::cout);
}
catch(const My_error&error) {
print_a_newline_if_necessary(std::cout);
std::cout<<error<<"\n";
}
(In reality, of course, we want to write error to std::cerr but that usually gets mixed in with std::cout unless one of them is redirected, so we still want to terminate the std::cout line before printing to std::cerr. I have deliberately simplified the example to avoid this distraction.)
You might imagine that os.tellp() would be the answer, but tellp() seems to work only on std::ofstream. For me at least, std::cout.tellp() always returns -1, indicating that it is not supported.
At least as I'm reading things, what you really want isn't the ability to get the position in the current line. Rather, what you really want is to be able to print something that is guaranteed to be at the start of a line--the current line if the immediately previous character was a newline (and, I'd guess also if it was a carriage return), but otherwise print a newline, then whatever follows.
Here's some code to do that:
#include <iostream>
class linebuf : public std::streambuf
{
std::streambuf* sbuf;
bool need_newline;
int sync() {
return sbuf->pubsync();
}
int overflow(int c) {
switch (c) {
case '\r':
case '\n': need_newline = false;
break;
case '\v':
if (need_newline) {
need_newline = false;
return sbuf->sputc('\n');
}
return c;
default:
need_newline = true;
break;
}
return sbuf->sputc(c);
}
public:
linebuf(std::streambuf* sbuf)
: sbuf(sbuf)
, need_newline(true)
{}
std::streambuf *buf() const { return sbuf; }
~linebuf() { sync(); }
};
class linestream : public std::ostream {
linebuf buf;
std::ostream &os;
public:
linestream(std::ostream& out)
: buf(out.rdbuf())
, std::ios(&buf)
, std::ostream(&buf)
, os(out)
{
out.rdbuf(&buf);
}
~linestream() { os.rdbuf(buf.buf()); }
};
void do_stuff() {
std::cout << "\vMore output\v";
}
int main() {
{
linestream temp(std::cout);
std::cout << "\noutput\n";
std::cout << "\voutput";
do_stuff();
std::cout << "\voutput\n";
std::cout << "\voutput\v";
}
std::cout << "\voutput\v";
}
Since it's almost never used otherwise, I've hijacked the vertical tab ('\v') to signify the special behavior.
To use it, you simply create a temporary object of type linestream (sorry, I'm too tired to think of a good name right now), passing it an ostream object that will get the new behavior when a \v gets written to it. When that temporary object goes out of scope, the stream will be restored to its original behavior (I doubt anybody uses \v often enough to care, but who knows maybe somebody care--it's mostly just a side effect of cleaning up after itself anyway).
In any case, the special behavior remains in place when do_stuff is called, so it's not just local to the function where the local linestream object is created, or anything like that--once it's created, the special behavior remains in effect until it's destroyed.
One other point though: when/if you mix output from cout and cerr, this won't help much. In particular, neither will be at all aware of the other's state. You'd probably much need some hooks into the output terminal (or something on that order) to be able to deal with that, since output redirection is normally handled by the OS, so inside the program there's no way to even guess whether data written to cout and cerr are going to the same place or not.

c++ unit testing check output is correct

If I want to write my own test.cpp that checks if another .cpp file is outputting the way I want it to output, is there anyway to do it without explicitly printing it?
In other words, is there anything such as
assert(output_of_file_being_tested, "this is the correct output");
where output_of_file_being_tested is something that's supposed to be "cout"ed.
The solution is not to hard-code the output stream. Pass a reference to std::ostream to your code somehow, and use std::stringstream to collect the output in test environment.
For example, this is the content of your "another .cpp" file:
void toBeTested(std::ostream& output) {
output << "this is the correct output";
}
So in your production/release code you may pass std::cout to the function:
void productionCode() {
toBeTested(std::cout);
}
while in the test environment you may collect the output to a sting stream and check it for correctness:
// test.cpp
#include <sstream>
#include <cassert>
void test() {
std::stringstream ss;
toBeTested(ss);
assert(ss.str() == "this is the correct output");
}
In addition to Sergey's great answer above, you may choose to have std::cout as a default parameter.
So, if you have a code:
// Only need console output
using std::cout;
...
void toBeTested()
{
cout << "This is the correct output.";
}
And it is used (or may be frequently used in the future) in many places:
int main()
{
...
toBeTested();
...
toBeTested();
...
// And so on...
return 0;
}
In order to avoid breaking a lot of code and maintaining a simple interface,
you can convert the above function to:
using std::cout;
...
void toBeTested(std::ostream& cout = std::cout)
{
cout << "This is the correct output.";
}
And your main does not need to be touched.
Note that cout of the function now overshadows cout of the global scope. Therefore, this cout can be any output stream, and does not interfere with the global cout.
And now you can test this as above!
#include <sstream>
#include <cassert>
...
void testMyFunctionDisplay()
{
// Arrange
std::ostringstream output_buffer;
// Act
toBeTested(output_buffer);
// Assert
assert(output_buffer.str() == "This is the correct output.");
}
However. it is not necessary to make every function in this way.
It is useful if we want to redirect that function's output to other output streams:
Stringstreams: If you want to use the output somewhere, perhaps for testing the module, or for other purposes in the program.
Files: If you want to maintain the output even after the program termination.

C++ destruction point guarantee multi-threading

I have the following simplified code at which while writing I thought was fine, but I have seem some random access violations.
Initially I thought as long as the arguments passed to async were on the stack, and not temporary variables, the code would be safe. I also thought that filename and extra data would destruct/considered not there at the brace where they leave scope.
It did some more research and read about the 'as if' principle that apparently compilers use for optimisation. I've often seen stack variables being optimised away in the debugger right after they have been used too.
My question here is basically, is it guaranteed that those stack variables will be around for the entire duration of the async function running. The .get() call on the future obviously synchronises the call before the two stack variables leave scope.
My current thinking is that it's not thread safe as the compiler can't see the variables being used after the call to the function, and therefore think it is safe to remove them. I can easily change the code to eliminate the problem (if there is one), but I really want to understand this.
The randomness of the AV, occurring more on some computers than others suggests it is a problem, and the scheduling order dictates whether this is a problem or not.
Any help is much appreciated.
#include <future>
#include <fstream>
#include <string>
#include <iostream>
int write_some_file(const char * const filename, int * extra_result)
{
std::ofstream fs;
try {
fs.open(filename);
} catch (std::ios_base::failure e) {
return 1;
}
fs << "Hello";
*extra_result = 1;
return 0;
}
int main(void)
{
std::string filename {"myffile.txt"};
int extraResult = 0;
auto result = std::async(std::launch::async, write_some_file, filename.c_str(), &extraResult);
// Do some other work
// ...
int returnCode = result.get();
std::cout << returnCode << std::endl;
std::cout << extraResult << std::endl;
return 0;
}

How to use insertion operator with a shared_ptr pointer of an ifstream object?

I am trying to read from a file using a shared_ptr pointer. I don't know how I can use insertion operator with it. Here is the code:
#include <iostream>
#include <regex>
#include <fstream>
#include <thread>
#include <memory>
#include <string>
#include <map>
using namespace std;
int main()
{
string path="";
map<string, int> container;
cout<<"Please Enter Your Files Path: ";
getline(cin,path);
shared_ptr<ifstream> file = make_shared<ifstream>();
file->open(path,ifstream::in);
string s="";
while (file->good())
{
file>>s;
container[s]++;
s.clear();
}
cout <<"\nDone..."<< endl;
return 0;
}
simply doing:
file>>s;
doesn't work.
How can I get the current value that file is pointing (I don't want to get the whole line, I just need to get the words and number of their occurrences this way).
By the way, I used shared_ptr to avoid closing the file myself, does making a pointer of this type, shared_ptr (smart) will it suffice not to write the file->close() myself ? or they are irrelevant?
The simplest way would be to use the dereference operator *:
(*file) >> s;
But looking at the code, I see no reason whatsoever to use a smart pointer. You could just use an ifstream object.
std::ifstream file(path); // opens file in input mode
Why do you want it to be a pointer? It's that that is causing you pain.
ifstream file;
file.open( ...
...
file>>s;
Streams are intended to be treated as value (rather than pointer types). The file will be closed when the destructor is called on the ifstream.
If you need to pass the stream object round other parts of your code, you simply use references (to the base class):
void other_fn( istream & f )
{
string something;
f>>something;
}
ifstream file;
other_fn( file );
Because the f parameter is a reference, it doesn't attempt to close the stream/file when it goes out of scope - that still happens in the scope that defines the original ifstream object.

Passing ofstream object from main program to a class

Here is what I am trying to do:
1) Open an ofstream object in my main body. I can do this no problem.
2) Associate this object with a filename. No problem.
3) Pass this object to a class and send output within this class. I can't do this.
Here is my code. I would appreciate any help. Thanks!
#include <fstream>
#include <iostream>
using namespace std;
typedef class Object
{
public:
Object(ofstream filein);
} Object;
Object::Object(ofstream filein)
{
filein << "Success";
}
int main (int argc, char * const argv[])
{
ofstream outfile;
outfile.open("../../out.txt");
Object o(outfile);
outfile.close();
return 0;
}
You must pass stream objects by reference:
Object::Object( ofstream & filein )
{
filein << "Success";
}
And why are you using a typedef on the class? It should look like this:
class Object
{
public:
Object(ofstream & filein);
};
It is worth mentioning, that in c++0x you will have another options (besides passing by reference or by pointer):
std::move. Streams are not copyable, but you will be able to move them into another place (it depends if streams will implement the move operator, but they probably will).
unique_ptr. Streams are not copyable. When using pointers, a risk of resource leak arises. Using shared_ptr incorporates unnecessary costs when you want to have streams stored in a collection, and nowhere else. Unique_ptr solves this. You will be able to store streams in a collection in safe and efficient way.