Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to print/format error messages in C++?

897 views
Skip to first unread message

Hongliang Wang

unread,
Sep 23, 2014, 10:00:15 AM9/23/14
to
Hello all, I used to be a C programmer and my way to print error messages is following:

1. Store all messages in a header file:

/* error.h */
#define ERROR_01 "Unable to open file: '%s'"

2. Include that header file in source file and use printf to print error messages.

/* source.c */
if (error) {
printf(ERROR_01, file_name);
exit(1);
}

Now I move to C++ but it seems that cout does not support %s thing.

So may I ask what is your way to print error messages? Is it still possible to put all error messages in a header file?

Thanks in advance.
Message has been deleted

Victor Bazarov

unread,
Sep 23, 2014, 10:50:27 AM9/23/14
to
There is no need for you to change anything. The C++ Standard library
includes the C Standard library, and 'printf' is still there. Only
switch to new C++ mechanisms when you find that old C ones don't work
anymore for you.

In a real-world application error messages are output to a special
window (if it's a GUI application) or to the console (like you have
there), and often also to a log (however that might be implemented).
The latter mechanism is frequently brought in from a 3rd party library.

V
--
I do not respond to top-posted replies, please don't ask

Wouter van Ooijen

unread,
Sep 23, 2014, 10:55:59 AM9/23/14
to
Hongliang Wang schreef op 23-Sep-14 3:59 PM:
C++ is a more-or-less superset of C, so you could simply do as you
always did.

A more C++-ish way would be to use exceptions:

// in the header file
class unable_to_open_file : public std::exception {
public:
unable_to_open_file( const std::string & name ):
s{ std::string{ "unable_to_poen_file [" } + name + "]" }
{}
const char * what() const override {
return s.c_str();
}
private:
std::string s;
};

// in the code
if (error) {
throw unable_to_open_file{ file_name };
}

Wouter van Ooijen

Drew Lawson

unread,
Sep 23, 2014, 10:57:39 AM9/23/14
to
In article <25e3b7c7-3ecd-4460...@googlegroups.com>
Hongliang Wang <loud...@gmail.com> writes:

>So may I ask what is your way to print error messages?

I use syslog(). Unfortunately for this discusson, that is not a
standard C++ component.

>Is it still possible to put all error messages in a header file?

You can put whatever you want in a header file.

--
Drew Lawson | "But the senator, while insisting he was not
| intoxicated, could not explain his nudity."

Christopher Pisz

unread,
Sep 23, 2014, 10:58:42 AM9/23/14
to
You don't need %s, because std::cout is a stream and the stream already
knows how to format a string. It also knows how to format other
primitive types. If you need it to format a custom class, you can supply
a function for that with your class. See the faq at
http://www.parashift.com/c++-faq/output-operator.html

Your code would be

/* error.h */ // You probably want a safer name here
#define ERROR_01 "Unable to open file"

/* source.c */
#include <iostream>

if (error)
{
// You could also use std::cerr instead of std::cout
std::cout << ERROR_01 << ": " << file_name;
exit(1); // Maybe throw or return error code here instead
}





Jorgen Grahn

unread,
Sep 23, 2014, 2:02:10 PM9/23/14
to
On Tue, 2014-09-23, Hongliang Wang wrote:
> Hello all, I used to be a C programmer and my way to print error messages is following:
>
> 1. Store all messages in a header file:
>
> /* error.h */
> #define ERROR_01 "Unable to open file: '%s'"
>
> 2. Include that header file in source file and use printf to print error messages.
>
> /* source.c */
> if (error) {
> printf(ERROR_01, file_name);
> exit(1);
> }

Why do you do that? The code would be much clearer (and easier to
translate to better C++) if it said something like:

/* source.c */
if (error) {
printf("Unable to open file: '%s'\n", file_name);
exit(1);
}

One valid reason to keep the actual text apart is if you need to
support different languages (i18n), but as I understand it there are
standard techniques for doing that if it is really needed -- if that
is what you're doing, ask specifically about that.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Paavo Helde

unread,
Sep 23, 2014, 2:22:33 PM9/23/14
to
Hongliang Wang <loud...@gmail.com> wrote in
news:25e3b7c7-3ecd-4460...@googlegroups.com:

> Hello all, I used to be a C programmer and my way to print error
> messages is following:
>
> 1. Store all messages in a header file:
>
> /* error.h */
> #define ERROR_01 "Unable to open file: '%s'"
>
> 2. Include that header file in source file and use printf to print
> error messages.
>
> /* source.c */
> if (error) {
> printf(ERROR_01, file_name);
> exit(1);
> }
>

In C++ errors should be reported via exceptions, the sooner you adapt to
this the better. Exit(1) (or 'return EXIT_FAILURE;') should reside only
in the catch handler in main().

When using exceptions, any error message has to be composed dynamically
in memory. In C++ there are several ways to do this type-safely and
without any buffer overflow dangers: direct string concatenation, string
streams, and also printf-style formatting utilities like boost.format.

About putting format strings in a separate header file - I still don't
get why these are considered useful, even in C. In simple programs it
just complicates the things, and for real i18n and such one needs much
more than that.

hth
Paavo

Scott Lurndal

unread,
Sep 23, 2014, 4:13:42 PM9/23/14
to
Paavo Helde <myfir...@osa.pri.ee> writes:
>Hongliang Wang <loud...@gmail.com> wrote in
>news:25e3b7c7-3ecd-4460...@googlegroups.com:
>
>> Hello all, I used to be a C programmer and my way to print error
>> messages is following:
>>
>> 1. Store all messages in a header file:
>>
>> /* error.h */
>> #define ERROR_01 "Unable to open file: '%s'"
>>
>> 2. Include that header file in source file and use printf to print
>> error messages.
>>
>> /* source.c */
>> if (error) {
>> printf(ERROR_01, file_name);
>> exit(1);
>> }
>>
>
>In C++ errors should be reported via exceptions, the sooner you adapt to
>this the better. Exit(1) (or 'return EXIT_FAILURE;') should reside only
>in the catch handler in main().

Frankly nonsense. Fix the error when it occurs, if possible. If not
possible to fix in place (i.e. ask for a new filename if the old one
couldn't be opened), log the message and terminate gracefully.


Ian Collins

unread,
Sep 23, 2014, 4:27:18 PM9/23/14
to
log the message and terminate gracefully in the catch handler in main()...

--
Ian Collins

Ian Collins

unread,
Sep 23, 2014, 4:37:55 PM9/23/14
to
Flippancy aside, the missing file case is a good example of an
appropriate use of an exception. In one context it might be a fatal
error while in another it might not. The function opening the file
doesn't necessarily know which.

--
Ian Collins

Dombo

unread,
Sep 23, 2014, 4:41:49 PM9/23/14
to
Op 23-Sep-14 22:13, Scott Lurndal schreef:
I have once had to deal with library that did that, and that basically
disqualified that library for use in our application because terminating
when an error was encountered was no acceptable for that application. In
non-trivial programs the point where the error condition is detected is
usually not right place to determine how the error condition should be
handled. Instead it should be escalated to higher levels which do have
sufficient context to properly handle the error condition. It is not
surprising that most popular programming languages conceived the last 20
years or so all have support for exceptions.

Dombo

unread,
Sep 23, 2014, 4:46:00 PM9/23/14
to
Op 23-Sep-14 15:59, Hongliang Wang schreef:
You might consider using a library like C++ Format or Boost.Format which
support format strings like printf() but also are type safe, which
printf() is not.

Lynn McGuire

unread,
Sep 23, 2014, 4:54:34 PM9/23/14
to
On 9/23/2014 8:59 AM, Hongliang Wang wrote:
This is the way that we use to create note, warning
and error messages. By using a std::string, you can
use variable typing in your error message.

std:string msg = "ERROR: blah blah blah";
msg += ", number: " + asString (errorNumber);
printf ("%s", msg.c_str ());

Lynn



Paavo Helde

unread,
Sep 23, 2014, 5:16:10 PM9/23/14
to
sc...@slp53.sl.home (Scott Lurndal) wrote in news:FvkUv.350614$8G3.201829
@fx12.iad:

> Paavo Helde <myfir...@osa.pri.ee> writes:
>>In C++ errors should be reported via exceptions, the sooner you adapt to
>>this the better. Exit(1) (or 'return EXIT_FAILURE;') should reside only
>>in the catch handler in main().
>
> Frankly nonsense. Fix the error when it occurs, if possible. If not
> possible to fix in place (i.e. ask for a new filename if the old one
> couldn't be opened), log the message and terminate gracefully.

This does not scale beyond simple command-line utilities. C++ is used for
other things, too. Do you seriously mean a web server should terminate
gracefully when somebody sends in an invalid URL?

OTOH, throwing an exception and terminating gracefully in main works fine
in simple command-line utilities.

Cheers
Paavo

Mr Flibble

unread,
Sep 23, 2014, 5:24:22 PM9/23/14
to
What you just said is nonsense mate. Manually returning and/or
translating error codes up the call stack is an ancient way of doing
things. In C++ prefer exceptions to error codes.

/Flibble

Scott Lurndal

unread,
Sep 24, 2014, 9:24:43 AM9/24/14
to
Dombo <do...@disposable.invalid> writes:
>Op 23-Sep-14 22:13, Scott Lurndal schreef:
>> Paavo Helde <myfir...@osa.pri.ee> writes:
>>> Hongliang Wang <loud...@gmail.com> wrote in
>>> news:25e3b7c7-3ecd-4460...@googlegroups.com:
>>>
>>>> Hello all, I used to be a C programmer and my way to print error
>>>> messages is following:
>>>>
>>>> 1. Store all messages in a header file:
>>>>
>>>> /* error.h */
>>>> #define ERROR_01 "Unable to open file: '%s'"
>>>>
>>>> 2. Include that header file in source file and use printf to print
>>>> error messages.
>>>>
>>>> /* source.c */
>>>> if (error) {
>>>> printf(ERROR_01, file_name);
>>>> exit(1);
>>>> }
>>>>
>>>
>>> In C++ errors should be reported via exceptions, the sooner you adapt to
>>> this the better. Exit(1) (or 'return EXIT_FAILURE;') should reside only
>>> in the catch handler in main().
>>
>> Frankly nonsense. Fix the error when it occurs, if possible. If not
>> possible to fix in place (i.e. ask for a new filename if the old one
>> couldn't be opened), log the message and terminate gracefully.
>
>I have once had to deal with library that did that, and that basically
>disqualified that library for use in our application because terminating

Libraries are different. And when I said terminate, that doesn't mean
calling exit, it must means terminating the function that detected
the error. That can be by returning an error code, or by signaling
an exception. I prefer libraries that return an error code rather than
raising an exception because the library can be used in more contexts
(I've rejected libraries that signalled via exceptions because the
code they were being used with didn't support exceptions at runtime).
0 new messages