Using perror with arguments

Viewed 492

Is it common to pass arguments to perror(), or is it usually used for a very generic message. For example, something like:

char buffer[50];
sprintf(buffer, "The file %s could not be opened", filename);
perror(buffer);

The reason I ask is because it seems the single arg to perror must be a string literal (without any format specifiers), and so perhaps it discourages using any variables?

Or, is there a shortform way to do something like:

perror("The file %s could not be opened", filename);

(Perhaps a macro?)

2 Answers

perror is declared as:

void perror(const char *s);

From the man page:

First (if s is not NULL and *s is not a null byte ('\0')), the argument string s is printed, followed by a colon and a blank. Then an error message corresponding to the current value of errno and a new-line.

From that, we then can assume that perror is basically defined as:

fprintf(stderr, "%s: %s\n", s, strerror(errno));

As a macro, it could be implemented as:

#define MY_PERROR(FMT,...) \
  fprintf(stderr, FMT ": %s\n", ##__VA_ARGS__, strerror(errno))

Based on your example the usage would be:

MY_PERROR("The file %s could not be opened", filename);

The output would look like:

The file <filename> could not be opened: <result of strerror>

You can use:

#include <string.h> /* for strerror()    */
#include <errno.h>  /* for errno         */
#include <stdlib.h> /* for EXIT_FAILURE  */
#include <fcntl.h>  /* open and O_RDONLY */

...

    if ((fd = open(file, O_RDONLY)) < 0) {
        fprintf(stderr, "open: %s: %s (errno = %d)\n",
                filename,
                strerror(errno),
                errno);
        exit(EXIT_FAILURE);
    }

and you are free of using whatever parameters you like.

Related