Here is an excerpt from the 1 November 1995 version of the comp.lang.c frequently asked questions list. The list is Copyright 1990-1995 by Steve Summit.
11.17: I'm trying to use the ANSI "stringizing" preprocessing operator `#' to insert the value of a symbolic constant into a message, but it keeps stringizing the macro's name rather than its value. A: You can use something like the following two-step procedure to force a macro to be expanded as well as stringized: #define Str(x) #x #define Xstr(x) Str(x) #define OP plus char *opname = Xstr(OP); This code sets opname to "plus" rather than "OP". An equivalent circumlocution is necessary with the token-pasting operator ## when the values (rather than the names) of two macros are to be concatenated. References: ANSI Sec. 188.8.131.52, Sec. 184.108.40.206 example; ISO Sec. 220.127.116.11, Sec. 18.104.22.168.
A full citation record for the FAQ (and expanded book version) is in my list of technical books.