#define NAME RAGHU
#define NAIVE_STR(x) #x
int main()
{
printf("%s", NAIVE_STR(NAME));
getch();
return 0;
}
how can we modify the code so that whatever we had defined in NAME get printed?
You can use something like
#define NAME RAGHU
#define NAIVE_STR(x) #x
#define DEF_TO_STRING(x) NAIVE_STR(x)
int main()
{
printf("%s", DEF_TO_STRING(NAME));
getch();
return 0;
}
This is how defines work. When you call NAIVE_STR(NAME) pre-processor sees #x and doesn't substitute x with it's value so string NAME is returned. But when you call DEF_TO_STRING(NAME) it doesn't see # and substitutes NAME with RAGHU and then calls NAIVE_STR(RAGHU) and NAIVE_STR(RAGHU) just returns RAGHU
Related
I am trying to specify the width of variables in a sscanf() call based on a #define that calculates its values based on another #define.
It works when the TEST define is just a single number, but when it becomes a calculation, the code fails. Have TEST call another function that contains the calculation does not work either.
The code I am working with:
#include <stdio.h>
#define A 3
#define TEST FUN()
#define FUN() (A + 2)
#define STR(X) _STR(X)
#define _STR(x) #x
int main()
{
char input[] = "Test123";
char output[10];
sscanf(input, "%" STR(TEST) "s\n", output);
printf("%s\n", output);
return 0;
}
What am I missing here?
You cannot realize an arithmetic operation as happened in your question. So, it is evaluated as (3 + 2) in string form while compiling.
My two cents reminiscent of the post,
#define STRING_LENGTH 20
#define STR(x) _STR(x)
#define _STR(x) #x
{
...
fscanf(input, "%" STR(STRING_LENGTH) "s", output);
...
}
Two macros are required because if you tried to use something like _STR directly you would just get the string "STRING_LENGTH" instead of its value.
For more click here and an example.
Just build the scanf format string during execution. For example:
const int width_modifier = FUN();
char fmt[100] = {0};
snprintf(fmt, sizeof(fmt), "%%%ds\n", width_modifier);
sscanf(input, fmt, output);
What am I missing here?
Preprocessor does text replacement, it doesn't calculate things. So "%" STR(TEST) "s\n" expands to a string containing "%" "3 + 2" "s\n", which after concatenation is "%3 + 2s", which is an invalid scanf format string.
Alternatively you can use other program to prepare the source file for compilation. A popular use is a preprocessor that preprocesses the file before compilation and that is able to calculate arithmetic. A popular choice is m4:
m4_define(`A', 3)
m4_define(`FUN', `eval(A + 2)')
#include <stdio.h>
#define STR(X) #X
int main() {
printf("%s", STR(FUN()));
}
preprocessed with m4 and compiled would output 5.
#include <stdio.h>
#include <string.h>
#define MAX_LENGTH 5
int main()
{
// specify format
char formatStr[20] = {0};
snprintf(formatStr, 20-1, "%s%d%s", "%", MAX_LENGTH-1, "s%u");
printf("%s\n", formatStr);
// example to use that format
char *input = "programming 123";
char dataStr[MAX_LENGTH] = {0};
int dataVal;
sscanf(input, formatStr, dataStr, &dataVal);
printf("%s-%d\n", dataStr, dataVal);
return 0;
}
output:
%4s%u
prog-21942
I'm a littlebit confused about the behaviour of preprocessing in c.
#include <stdio.h>
#define myMacro anotherMacro
#define anotherMacro 6
int main()
{
int dummy = myMacro;
printf("dummy = %d", dummy);
return 0;
}
in the above code snippet, the result will 6. however the the macro expansion in the initial pass will replace "myMacro" by "anotherMacro".
this is means that preprocessor will make a second pass to resolve "anotherMacro" to value 6.
The preprocessor will make a second pass. He works through the source file line per line.
So if he reaches the first define
#define myMacro anotherMacro
he will replace all occurrences of myMacro with the string anotherMacro.
The file will look like this after the line is handled:
#include <stdio.h>
#define anotherMacro 6
int main()
{
int dummy = anotherMacro;
printf("dummy = %d", dummy);
return 0;
}
Now the preprocessor could continue with the next #define
and replace every anotherMacro with the text 6
In this example code a macro is either defined or commented out by the programmer in order to remove a function from the released software.
#include <stdio.h>
#define MACRO //or omitted
#ifdef MACRO
void Function(const char* str)
{
printf("%s\n", str);
}
#else
#define Function(str)
#endif
int main(void)
{
Function("hello world");
getchar();
return 0;
}
Is there anything wrong with this?
Even though your solution works, I prefer the following approach:
#include <stdio.h>
#define MACRO //or omitted
#ifdef MACRO
#define FUNCTION(a) Function(a);
#else
#define FUNCTION(a)
#endif
#ifdef MACRO
void Function(const char* str)
{
printf("%s\n", str);
}
#endif
int main(void)
{
FUNCTION("hello world")
getchar();
return 0;
}
Note: FUNCTION is the macro, Function is the actual name of the function
This works by defining the macro FUNCTION(a) to a call to Function(const char*) when MACRO is enabled. On the other hand, when MACRO is disabled, calls to FUNCTION(a) will be defined to nothing.
I tend to prefer this method since it would be easier to abstract away the macro used to define your call from the macro defining your function definition. You might have cases where in release mode you only need to remove some of the calls to Function. In that case the definition of Function() is still required. For example:
#include <stdio.h>
#define DEBUG //or omitted
#ifdef DEBUG
#define FUNCTION(a) Function(a);
#else
#define FUNCTION(a)
#endif
void Function(const char* str)
{
printf("%s\n", str);
}
int main(void)
{
// Call function with Hello World only in debug
FUNCTION("hello world")
getchar();
// Call function with goodbye world in both debug and release
Function("goodbye world");
return 0;
}
It will work. But the entire symbol is removed this way. I prefer the following method.
#include <stdio.h>
#define MACRO 1
#if MACRO
void Function(const char* str)
{
printf("%s\n", str);
}
#else
void Function(const char *str){}
#endif
int main(void)
{
Function("hello world");
getchar();
return 0;
}
The following has changed:
The #if now compares a boolean. Your IDE is now able to find where MACRO is defined, in all cases. (right click, find definition)
You can, by changing MACRO to 2, change the entire meaning of Function. For example, a release compiled variant might contain a print to file or system log.
There will always be a symbol for Function, even if it does nothing, even in compiled code. This has the benefit that the string literals in the argument still count to the size statistics. As an embedded developer, I find this important.
Obviously, this is partly the preference of the one who crafts the code.
Say I have some C code like:
#define FOO 2
#define BAR 3
#define BAZ 500
void get_value(int val) {
printf("The value is %s\n", some_function_or_macro_or_something(val));
}
int main(int argc, char** argv) {
get_value(BAZ);
get_value(FOO);
return 0;
}
and I want it to print out
"The value is BAZ"
and
"The value is FOO". But there are thousands of #defines, so I want to do it programmatically.
C is definitely capable of doing this using # stringizing operator, but you need to call macro with identifier directly:
#include <stdio.h>
#define FOO 2
#define BAR 3
#define BAZ 500
#define get_value(val) \
printf("The value is %s\n", #val);
int main(void)
{
get_value(BAZ);
get_value(FOO);
return 0;
}
In your example after passing value of e.g. BAZ to get_value function, the token BAZ is not recognized anymore, as arguments are passed by value. In other words macro identifier is gone (of course you can still stringize its replacement, see comment below).
What can I do more?
Here is some small hack to obey this "top-level" rule. Assuming that you have small amount of object-like macros (constants) with unique values, then you can do something like:
#include <stdio.h>
#define FOO 2
#define BAR 3
#define BAZ 500
#define STRINGIFY(val) #val
void get_value(int val) {
switch (val) {
case FOO :
printf("The value is %s\n", STRINGIFY(FOO)); break;
case BAR :
printf("The value is %s\n", STRINGIFY(BAR)); break;
case BAZ :
printf("The value is %s\n", STRINGIFY(BAZ)); break;
}
}
int main(int argc, char* argv) {
get_value(BAZ);
get_value(FOO);
return 0;
}
Result:
The value is BAZ
The value is FOO
Use the right tool for the job. Which tool knows all about macros? A compiler.
GNU gcc and clang both allow to dump the list of defined macros:
$ cc -E -dM -x c /usr/include/stdio.h
#define BUFSIZ 1024
#define EOF (-1)
#define FILENAME_MAX 1024
#define FOPEN_MAX 20
#define L_ctermid 1024
#define L_cuserid 17
#define L_tmpnam 1024
#define NULL ((void *)0)
#define P_tmpdir "/tmp/"
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
/* etc */
will list the whole shebang defined by <stdio.h> and everything it includes.
If you need to process this data programmatically in a C program,
#include <stdio.h>
#define BIG_ENOUGH 1024
int main (void)
{
char buffer[BIG_ENOUGH];
FILE *fp = popen ("cc -E -dM -x c /usr/include/stdio.h", "r");
while (fgets(buffer, sizeof buffer, fp) != NULL) {
char identifier[BIG_ENOUGH];
int value;
if (sscanf (buffer, "#define %s %d", identifier, &value) == 2) {
printf ("value %d is from macro %s\n", value, identifier);
}
}
fclose(fp);
return 0;
}
This prints here for stdio.h
value 1024 is from macro BUFSIZ
value 1024 is from macro FILENAME_MAX
value 20 is from macro FOPEN_MAX
value 1024 is from macro L_ctermid
value 17 is from macro L_cuserid
value 1024 is from macro L_tmpnam
value 1 is from macro SEEK_CUR
value 2 is from macro SEEK_END
value 0 is from macro SEEK_SET
value 308915776 is from macro TMP_MAX
[...]
Instead of stdio.h you simply use your file.c as input.
The classical, if somewhat heavyweight, approach is a table file:
enum.tab:
#ifndef DECL_CONST
# define DECL_CONST(name, value)
#endif
DECL_CONST(FOO, 2)
DECL_CONST(BAR, 3)
DECL_CONST(BAZ, 500)
#undef DECL_CONST
enum.h:
enum My_Enum
{
#define DECL_CONST(name, value) name = value,
#include "enum.tab"
};
char const* get_name(enum My_Enum value);
enum.c:
#include "enum.h"
char const* get_name(enum My_Enum value)
{
switch (value)
{
#define STR(name) #name
#define DECL_CONST(name, value) case value: return STR(name);
#include "enum.tab"
default:
return 0;
}
}
main.c:
#include "enum.h"
void process_value(int v)
{
char const* s = get_name((enum My_Enum) v);
if (s)
printf("The name of value %d is %s\n", v, s);
else
printf("There is no name for value %d\n", v);
}
int main()
{
process_value(1);
process_value(2);
process_value(3);
process_value(500);
process_value(501);
return 0;
}
Of course, you can expand this basic scheme to include as many attributes as you like and support any number of dependencies between them. Note that if you have more than one name defined to the same value, the compilation of switch statement will fail.
Not sure it is possible. GCC states in their manual :
There is no way to convert a macro argument into a character constant.
I have a file with about 100 #defines in it, from 1-100, and each with a unique string value.
Now I'm trying to print this value, but instead of the value, I want to print what the #define is. For example:
#define FIRST_VALUE 1
var = FIRST_VALUE;
printf("%s", var);
and I want the printf to print FIRST_VALUE, not 1.
Is there any way to do this in C? Or must I just write out 100+ case blocks inside a switch statement?
You can use stringification to achieve what you are looking for:
#define FIRST_MACRO
#define MACRO_TO_STRING(x) #x
#include <stdio.h>
main() {
printf("%s\n", MACRO_TO_STRING(FIRST_MACRO));
}
This program will output:
FIRST_MACRO
After talking to one of my TA's at school, we've decided that the best way to do this would be to write an AWK script to process the header file and automatically generate all the case statements needed.
Thanks guys!
You can't do exactly what you want, since by the time the compiler gets the pre-processor output, the "ONE" token is long gone. However, if your goal is to write the list of constants once but generate both tokens and strings, then this can be done.
First, use a macro to build the constants as enums in a header file. File enums.h:
#ifndef ENUMS_H
#define ENUMS_H
#ifndef ENUM
#define ENUM(name,val) enum { name = val };
#endif
ENUM(ONE,1)
ENUM(TWO,2)
ENUM(THREE,3)
#endif /* ENUMS_H */
Second, redefine the macro in a .c file to create a string/integer mapping and include the .h file in the right place. File enums.c:
#include
#include
typedef struct {
char *str;
int val;
} DescriptiveEnum;
static DescriptiveEnum enums[] = {
#define ENUM(name,val) { #name, val },
#include "enums.h"
};
#define NUM_ENUMS (sizeof(enums)/sizeof(enums[0]))
char *enum_to_str(int val)
{
int i;
for (i=0;i<NUM_ENUMS;i++) {
if (enums[i].val == val) return enums[i].str;
}
return "";
}
Now both the enum constants and the mapping function are available to callers. File main.c:
#include <stdio.h>
#include <stdlib.h>
#include "enums.h"
char *enum_to_str(int val);
int main(int argc, char *argv[])
{
int val;
val = ONE;
printf("%d %s\n",val,enum_to_str(val));
return EXIT_SUCCESS;
}