Is it in good style do use cerr in situation described below?
try
{
cout << a + b;
}
catch(const IntException& e)
{
cerr << "Exception caught: " << typeid(e).name(); //using cerr not cout
}
catch(...)
{
cerr << "Unknown exception.";//using cerr not cout
}
or cout should be used? See comments in code.
stderr is the traditional stream to send error messages (so that the OS/shell/whatever can capture error messages separately from "normal" output), so yes, use std::cerr!
I make no comment as to whether catching an exception simply to print it out is any better than simply letting the exception propagating out of your application...
Yes, because while by default they both go to the terminal, you could change where their output is directed, and you may wish cerr to go to a log file while cout continues to just go to stdout.
Essentially it gives you more control over where different output goes if you want it now or in the future.
Sure, it's good to use cerr there. You can redirect cerr differently from cout, sometimes that helps you to highlight problems that could go buried in a huge cout log file.
One detail to keep in mind is that sending output directly to the terminal (with either cout or cerr), you do limit your ability to test for your error messages. It's always worth posing the question "How do I unit test this?".
Related
I don't get why "cout" outputs after the file is written, it makes no sense to me... How would I do it correctly? I tried with sleep between the two, but it's still not reversing the order like I want to.
cout << "Writing to file";
fp = fopen("plume_visualisation.txt","w");
for(int i=0;i<grid;i++)
for(int j=0;j<grid;j++)
for(int k=0;k<grid;k++)
fprintf(fp,"%f\t%f\t%f\t%f\n",x[i],y[j],z[k],suv[i][j][k]);
fclose(fp);
C++ writes to the output stream, stored in a buffer. You need to flush the buffer to write it to the console. Remember how you probably learned to write a line to the console?
std::cout << "This is a message" << std::endl;
What std::endl does is place a newline character at the end of the message, and flush the buffer. Based on your code, I'm guessing you thought "Hey, I can just leave off endl and it won't write a new line." This is a good way to think...but you probably didn't realize that endl also flushes the buffer. This is what you want:
std::cout << "Writing to file" << std::flush;
Also notice how I prefixed cout and flush with "std." Using "using namespace standard" is bad practice that you should avoid.
On a related note, you're already using C++. Instead of doing file IO the old C way of fprintf, instead set up a file stream. It works pretty much the same way that console IO does. Here's a great guide on how to do what you're doing in a more idiomatic fashion: http://www.cplusplus.com/doc/tutorial/files/
When developing code, I have many console logging (std::clog) and some console output (std::cout). But now, I wanted to do online submission of my source code and I want to disable all the console logging (clog) but keep the console output (cout)
I can surely comment all of my //std::clog, but is there a better way to disable all logging inside my source file,?
You can redirect clog, create your own ofstream and use rdbuf function.
std::ofstream nullstream;
std::clog.rdbuf(nullstream.rdbuf());
Copied from Andreas Papadopoulos' answer to a slightly different question -- be sure to upvote him there!
Sure, you can (example here):
int main() {
std::clog << "First message" << std::endl;
std::clog.setstate(std::ios_base::failbit);
std::clog << "Second message" << std::endl;
std::clog.clear();
std::clog << "Last message" << std::endl;
return 0;
}
Outputs:
First message
Last message
This is because putting the stream in fail state will make it silently discard any output, until the failbit is cleared.
I recently included a redis connection into one of my c++ programs. I decided to use the redox library since it seemed easy to use and does not depend on the boost library.
I use the connection to insert a value into a list in redis. The command works most of the times, but sometimes I get an error message saying that Received reply of type 3, expected type 1 or 5. After extensive search, I found these return types in the hiredis.h header file. It seems like the library expects a String or Status reply type but receives an Integer type.
Unfortunately I was not yet able to find any information about what this means and how I can fix the problem. Especially the fact that the codes sometimes works and sometimes does not confuses me.
In my use case I insert a string value containing a json dictionary in celery format (but essentially just a string) into a list. I am pretty sure that it has nothing to do with the way the string is composed as inserting the same string by hand via the redis-cli client works fine.
My code for inserting the message is:
redox::Redox rdx;
try {
if(!rdx.connect("localhost", 6379)){
cerr << "Could not connect to redis" << endl;
}
redox::Command<string>& c = rdx.commandSync<string>({"lpush", "queue_name", message});
if(!c.ok()) {
cerr << "Error while communicating with redis" << c.status() << endl;
}
} catch (runtime_error& e) {
cerr << "send_message: Exception in redox: " << e.what() << endl;
}
The error that is printed is the one after the !c.ok() check.
Thank you for your help.
The problem that you have is due to the fact that you use string as parameter to the response.
As mentioned in the documentation of redox:
This statement tells redox to run the command GET hello. The <string> template parameter means that we want the reply to be put into a string and that we expect the server to respond with something that can be put into a string
But that works because the example was using the "GET" command which is expected to return a string. In the case of the "LPUSH" command that you are using the return result is an integer as can be seen when issuing the command using redis-cli
127.0.0.1:6379> lpush "test" test
(integer) 1
So you must use a response with an integer parameter, the complete list of the possible response as listed here is:
<redisReply*>: All reply types, returns the hiredis struct directly
<char*>: Simple Strings, Bulk Strings
<std::string>: Simple Strings, Bulk Strings
<long long int>: Integers
<int>: Integers (careful about overflow, long long int recommended)
<std::nullptr_t>: Null Bulk Strings, any other receiving a nil reply will get a NIL_REPLY status
<std::vector<std::string>>: Arrays of Simple Strings or Bulk Strings (in received order)
<std::set<std::string>>: Arrays of Simple Strings or Bulk Strings (in sorted order)
<std::unordered_set<std::string>>: Arrays of Simple Strings or Bulk Strings (in no order)
So something like this would do:
redox::Redox rdx;
try {
if(!rdx.connect("localhost", 6379)){
cerr << "Could not connect to redis" << endl;
}
redox::Command<int>& c = rdx.commandSync<int>({"lpush", "queue_name", message});
if(!c.ok()) {
cerr << "Error while communicating with redis" << c.status() << endl;
}}catch (runtime_error& e) {
cerr << "send_message: Exception in redox: " << e.what() << endl;
}
Or if using a lamda:
redox::Redox rdx;
try {
if(!rdx.connect("localhost", 6379)){
cerr << "Could not connect to redis" << endl;
}
rdx.commandSync<int>(
{"lpush", "queue_name", message},
[](redox::Command<int>& response){
if(!response.ok()){
cerr << "Error while communicating with redis" << c.status() << endl;
}});
}catch (runtime_error& e) {
cerr << "send_message: Exception in redox: " << e.what() << endl;
}
I often use cout for debugging purpose in many different places in my code, and then I get frustrated and comment all of them manually.
Is there a way to suppress cout output in the runtime?
And more importantly, let's say I want to suppress all cout outputs, but I still want to see 1 specific output (let's say the final output of the program) in the terminal.
Is it possible to use an ""other way"" of printing to the terminal for showing the program output, and then when suppressing cout still see things that are printed using this ""other way""?
Sure, you can (example here):
int main() {
std::cout << "First message" << std::endl;
std::cout.setstate(std::ios_base::failbit);
std::cout << "Second message" << std::endl;
std::cout.clear();
std::cout << "Last message" << std::endl;
return 0;
}
Outputs:
First message
Last message
This is because putting the stream in fail state will make it silently discard any output, until the failbit is cleared.
To supress output, you can disconnect the underlying buffer from cout.
#include <iostream>
using namespace std;
int main(){
// get underlying buffer
streambuf* orig_buf = cout.rdbuf();
// set null
cout.rdbuf(NULL);
cout << "this will not be displayed." << endl;
// restore buffer
cout.rdbuf(orig_buf);
cout << "this will be dispalyed." << endl;
return 0;
}
Don't use cout for debugging purposes, but define a different object (or function, or macro) that calls through to it, then you can disable that function or macro in one single place.
You can user cerr - standard output stream for errors for your debug purposes.
Also, there is clog - standard output stream for logging.
Typically, they both behave like a cout.
Example:
cerr << 74 << endl;
Details: http://www.cplusplus.com/reference/iostream/cerr/
http://www.cplusplus.com/reference/iostream/clog/
If you include files which involve cout you may want to write the code at the start (outside of main), which can be done like this:
struct Clearer {
Clearer() { std::cout.setstate(std::ios::failbit); }
} output_clearer;
It seems you print debug messages. You could use TRACE within Visual C++/MFC or you just might want to create a Debug() function which takes care of it. You can implement it to turn on only if a distinct flag is set. A lot of programs use a command line parameter called verbose or -v for instance, to control the behavior of their log and debug messages.
I'm trying to to the most basic of things .... write a file in C++, but the file is not being written. I don't get any errors either. Maybe I'm missing something obvious ... or what?
I thought there was something wrong with my code, but I also tried a sample I found on the net and still no file is created.
This is the code:
ofstream myfile;
myfile.open ("C:\\Users\\Thorgeir\\Documents\\test.txt");
myfile << "Writing this to a file.\n";
myfile.close();
I've also tried creating the file manually beforehand, but it's not updated at all.
I'm running Windows 7 64bit if that has got something to do with this. It's like file-write operations are completely forbidden and no error messages or exceptions are shown.
You need to open the file in write mode:
myfile.open ("C:\\Users\\Thorgeir\\Documents\\test.txt", ios::out);
Make sure to look at the other options for that second argument, as well. If you're writing binary data you'll need ios::binary for example.
You should also be checking the stream after opening it:
myfile.open(...
if (myfile.is_open())
...
Update:
AraK is right, I forgot that an ofstream is in write mode by default, so that's not the problem.
Perhaps you simply don't have write/create permissions to the directory? Win7 defaults a lot of directories with special permissions of "deny all". Or perhaps that file already exists and is read-only?
Start off by turning that slash around.
Even Windows understands the slash being the other way around.
ofstream myfile("C:/Users/Thorgeir/Documents/test.txt");
You could test if there are any errors:
if (!myfile)
{
std::cout << "Somthing failed while opening the file\n";
}
else
{
myfile << "Writing this to a file.\n";
myfile.close();
}
Make sure the directory exists.
If the file exists make sure it is writeable (by you)
Check the directory you are writing into is writeable (by you)
Have you read about UAC (User Account Control) and UAC Virtualization / Data Redirection in Windows Vista and 7? It's possible that your file is actually in the Virtual Store.
User Account Control Data Redirection
Your example output directory is in Users, so I wouldn't think this would be the issue, but it's a possibility worth mentioning and something that can be very frustrating if you're not looking out for it!
Hope this helps.
This code should catch any error. Most likely it's a permissions thing if any errors are encountered. Make sure you can read/write to the folder you're creating the file in.
#include "stdafx.h"
#include <fstream>
#include <iostream>
bool CheckStreamErrorBits(const std::ofstream& ofile);
int _tmain(int argc, _TCHAR* argv[]) {
std::ofstream ofile("c:\\test.txt");
if(ofile.is_open()) {
CheckStreamErrorBits(ofile);
ofile << "this is a test" << std::endl;
if(CheckStreamErrorBits(ofile)) {
std::cout << "successfully wrote file" << std::endl;
}
}else {
CheckStreamErrorBits(ofile);
std::cerr << "failed to open file" << std::endl;
}
ofile.close();
return 0;
}
//return true if stream is ok. return false if stream has error.
bool CheckStreamErrorBits(const std::ofstream& ofile) {
bool bError=false;
if(ofile.bad()) {
std::cerr << "error in file stream, the bad bit is set" << std::endl;
bError=true;
}else if(ofile.fail()) {
std::cerr << "error in file stream, the fail bit is set" << std::endl;
bError=true;
}else if(ofile.eof()) {
std::cerr << "error in file stream, the eof bit is set" << std::endl;
bError=true;
}
return !bError;
}
Update:
I just test my code under Windows 7 Enterprize and it failed the first time (fail bit was set). Then I turn off User Account Control (UAC) and tested again and it wrote the file. That is probably the same problem you're seeing. To turn off UAC go to:
Control Panel (view by Small icons) | User Accounts | Change User Account Control settings. Set it to Never notify then click OK button. You will have to restart for the changes to take affect.
I'm curious how to make it work with UAC on, i'll look into that.
Try this:
if( ! myfile)
{
cerr << "You have failed to open the file\n";
//find the error code and look up what it means.
}
Use FileMon and look for failed WriteFile calls from your process.