Is is possible to convert any variable of any type to string?
I wrote the following
#define TO_STRING(val) #val
Is this a valid way of converting a variable into a string?
I think the code below will do your work. I uses the standard sprintf function, which prints data from any type to a string, instead to stdout. Code:
#include <stdio.h>
#define INT_FORMAT "%d"
#define FLOAT_FORMAT "%f"
#define DOUBLE_FORMAT "%lf"
#define LL_FORMAT "%lld"
// ect ...
#define CONVERT_TO_STRING(FORMAT, VARIABLE, LOCATION) \
do { \
sprintf(LOCATION, FORMAT, VARIABLE); \
} while(false)
int main() {
char from_int[30];
char from_float[30];
char from_double[30];
char from_ll[30];
CONVERT_TO_STRING(INT_FORMAT, 34, from_int);
CONVERT_TO_STRING(FLOAT_FORMAT, 34.234, from_float);
CONVERT_TO_STRING(DOUBLE_FORMAT, 3.14159265, from_double);
CONVERT_TO_STRING(LL_FORMAT, 9093042143018LL, from_ll);
puts(from_int);
puts(from_float);
puts(from_double);
puts(from_ll);
return 0;
}
You will get a string version of the variable's name, i.e. it will convert a to "a". The #when used like this is called the stringification operator.
For example:
#define TO_STRING(val) #val
int main(void)
{
const int a = 12;
print("a is %s\n", TO_STRING(a));
return 0;
}
This will print a is a.
What do you expect to happen?
You can't get the variable's value, of course, since that's not available when the pre-processor runs (which is at compile-time).
try this will work with integers: edit the format string for other data types.
sprintf(str,"%d",value);
Related
This questions is about my homework.
This topic is need to use like:
#define GENERIC_MAX(type)\
type type##_max(type x, type y)\
{\
return x > y ? x : y;\
}
The content of the question is to make this code run normally:
#include <stdio.h>
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
The result of the operation is like this:
i=5.2000
j=3
And this code is my current progress, but there are have problems:
#include <stdio.h>
#define printname(n) printf(#n);
#define GenerateShowValueFunc(type)\
type showValue_##type(type x)\
{\
printname(x);\
printf("=%d\n", x);\
return 0;\
}
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
I don’t know how to make the output change with the type, and I don’t know how to display the name of the variable. OAO
This original task description:
Please refer to ShowValue.c below:
#include <stdio.h>
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
Through [GenerateShowValueFunc(double)] and [GenerateShowValueFunc(int)] these two lines macro call, can help us to generated as [showValue_double( double )] and [showValue_int( int )] function, And in main() function called. The execution result of this program is as follows:
i=5.2000
j=3
Please insert the code that defines GenerateShowValueFunc macro into the appropriate place in the ShowValue.c program, so that this program can compile and run smoothly.
A quick & dirty solution would be:
type showValue_##type(type x)\
{\
const char* double_fmt = "=%f\n";\
const char* int_fmt = "=%d\n";\
printname(x);\
printf(type##_fmt, x);\
return 0;\
}
The compiler will optimize out the variable that isn't used, so it won't affect performance. But it might yield warnings "variable not used". You can add null statements like (void)double_fmt; to silence it.
Anyway, this is all very brittle and bug-prone, it was never recommended practice to write macros like these. And it is not how you do generic programming in modern C. You can teach your teacher how, by showing them the following example:
#include <stdio.h>
void double_show (double d)
{
printf("%f\n", d);
}
void int_show (int i)
{
printf("%d\n", i);
}
#define show(x) _Generic((x),\
double: double_show, \
int: int_show) (x) // the x here is the parameter passed to the function
int main()
{
double i = 5.2;
int j = 3;
show(i);
show(j);
}
This uses the modern C11/C17 standard _Generic keyword, which can check for types at compile-time. The macro picks the appropriate function to call and it is type safe. The caller doesn't need to worry which "show" function to call nor that they pass the correct type.
Without changing the shown C-code (i.e. only doing macros), which I consider a requirement, the following code has the required output:
#include <stdio.h>
#define showValue_double(input) \
showValueFunc_double(#input"=%.4f\n" , input)
#define showValue_int(input) \
showValueFunc_int(#input"=%d\n" , input)
#define GenerateShowValueFunc(type) \
void showValueFunc_##type(const char format[], type input)\
{\
printf(format, input); \
}
/* ... macro magic above; */
/* unchangeable code below ... */
GenerateShowValueFunc(double)
GenerateShowValueFunc(int)
int main()
{
double i = 5.2;
int j = 3;
showValue_double(i);
showValue_int(j);
}
Output:
i=5.2000
j=3
Note that I created something of a lookup-table for type-specific format specifiers. I.e. for each type to be supported you need to add a macro #define showValue_ .... This is also needed to get the name of the variable into the output.
This uses the fact that two "strings" are concatenated by C compilers, i.e. "A""B" is the same as "AB". Where "A" is the result of #input.
The rest, i.e. the required function definition is very similar to the teacher-provided example, using the ## operator.
Note, this is if the variable name has to correctly be mentioned in the output.
With out the i = things would be easier and would more elegantly use the generated functions WITHOUT having the called showValue_double(i); be explicit macros. I.e. the functions generated are 1:1 what is called from main(). I think that might be what is really asked. Let me know if you want that version.
I am trying to create a macro in c, that will take a variable name, and declare it. I could call it like this:
MY_MACRO(test);
Would produce:
int test;
In order to achieve this I went this way:
#define MY_MACRO(var) /
int ##var; /
But the compiler doesn't understand this. Does such syntax exist in C11?
I wouldn't recommend doing such a thing. Anyway, there are two problems. First of all, to skip a newline, you need \, not /.
Second, the ## is wrong. What it does is concatenating the var to the int. So with MY_MACRO(foo) you would get intfoo;, but you want int foo;
The macro needs to be like this:
#define MY_MACRO(var) \
int var
## is not applicable here as it concatenates the token with something else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MY_MACRO(var) int var
or
#define MY_MACRO(var) \
int var \
void foo(void)
{
MY_MACRO(a);
a = rand();
printf("%d\n",a);
}
## pastes two tokens together into one token.
#define poem(var)\
int jack##var;
// Produces 'int jacksprat;'
poem(sprat)
In your case you don't need to do anything special at all, you can just use the argument directly:
#define MY_MACRO(var)\
int var;
The correct syntax would be something along the lines of this:
#define MY_MACRO(ident) \
int ident
int main() {
MY_MACRO(test);
test =42;
return test;
}
However, have you been looking into typedefs? Unlike typedefs, macros are considered bad practice.
In the project that I'm working on I have a code similar to this one:
#include<stdio.h>
struct parameter_struct{
char *parameter_name;
int parameter_value;
};
int main(){
struct parameter_struct param1= {"x_custom_param1", 6};
printf("parameter name: %s\n", param1.parameter_name);
return 0;
}
what I need to achieve now is to make the parameter name dynamic using predefined macro:
#define macro_custom "x_custom1_"
so the parameter name should be the macro value concatenated with "param1" substring. I mean it will be "x_custom1_param1" instead of the actual static value "x_custom_param1".
In my project all parameters are statically declared like that:
{"x_custom_param1", 6};
and I mustn't touch this structure of code. So I can't initialize those parameters dynamically in c function for example and use strcat in this function.
So what I thought about is to use an other #define with ## statement. So my code will be like that:
#include<stdio.h>
#define macro_custom "x_custom1_"
#define f(g,h) g##h
struct parameter_struct{
char *parameter_name;
int parameter_value;
};
int main(){
struct parameter_struct param1= {f(macro_custom, "param1"), 6};
printf("parameter name : %s\n", param1.parameter_name);
return 0;
}
but I get a compilation error:
error: pasting "macro_custom" and ""param1"" does not give a valid preprocessing token
struct parameter_struct param1= {f(macro_custom, "param1"), 6};
and that seems logical because the macro that I defined doesn't return a string with ##
Has someone an idea how I can correct my idea? or is there a better idea?
The feature you are looking for is string pasting. Adjacent string constants will be combined by the compiler -- you don't need an operator.
#define f(g, h) (g h)
Keep in mind that this trick only works for string constants. It won't work on variables.
it's simpler then what I thought. I found it in an old project.
#include<stdio.h>
#define macro_custom "x_custom1_"
struct parameter_struct{
char *parameter_name;
int parameter_value;
};
int main(){
struct parameter_struct param1= {macro_custom"param1", 6};
printf("parameter name : %s\n", param1.parameter_name);
return 0;
}
String literals can be concatenated this way "str1""str2"
macro function can concatenate two string literals - #define STRCAT(str1, str2) str1##str2
And when it comes to variables, you use strcat()
More efficient approach is to use string managing utilities such as GString.
It keeps track of the end of string and it handles memory expansions for you.
Keeping track of the end of string is always cost-free operation, as you always reach the end when copying it anyway.
Another approach is to use strchr() to find \0 and then copy string with conventional methods at this offset plus one byte forwards.
Also, I think OP's question would be much clearer if it states that string concatenation at compile / pre-processor (the comment belows throws some light on the exact phase it happens in) time is needed.
Those concepts uncover entire different universes.
Try the ‘#’ preprocessing operator which convert a macro argument into a string constant.
#define NEW_PARA_STRUCT(paramx, value) struct parameter_struct paramx={(macro_custom #paramx), value}
Example:
#include <stdio.h>
#define macro_custom "x_custom1_"
#define f(g,h) (g h)
#define NEW_PARA_STRUCT(paramx, value) struct parameter_struct paramx={(macro_custom #paramx), value}
struct parameter_struct{
char *parameter_name;
int parameter_value;
};
int main(){
struct parameter_struct param1= {f(macro_custom, "param1"), 6};
NEW_PARA_STRUCT(param2, 7);
printf("parameter name : %s\n", param1.parameter_name);
printf("parameter name : %s\n", param2.parameter_name);
return 0;
}
I have a printf statement as follows:
printf("[%d] %d", i, n->data);
I'm trying to make the related code flexible so you can change the variable type of "n->data" depending on your need. Is there a way to make the format specifier update depending on the variable type used?
I've tried including:
const char FS[2] = "%f";
when the variable is a float, then amending the printf statement to:
printf("[%d] "FS, i, n->data);
but this gets the following error, which I don't know how to resolve:
dLList.c:125:23: error: expected ')'
printf("[%d] "FS, i, n->data);
^
dLList.c:125:15: note: to match this '('
printf("[%d] "FS, i, n->data);
^
1 error generated.
Any ideas?
Thanks
Instead of const char FS[2] = "%f";, you may try to use macro like this:
#define FS "%f"
that would aggregate the control string format as you apparently want.
Is there a way to make the format specifier update depending on the variable type used?
Yes, C11 has _Generic. This allows code selection based on the type of the expression. The selection is not evaluated at run-time, but at compile time, the type is determined.
#include <stdio.h>
#include <stdlib.h>
#define print(X) printf(_Generic((X), \
double: "%e\n", \
int: "%i\n", \
char *: "%s\n", \
default: "TBD" \
) , X)
int main(void) {
print(5.0);
print(5);
print("Five");
print(1.0f);
return 0;
}
Output
5.000000e+00
5
Five
TBD
You could use an enum and a lookup table for format strings.
Just make sure your struct that contains the data also contains a matching enum describing the type of data currently contained in the struct.
That way you can write a print function that accepts such a struct as an argument and prints its value using a correct format string for that type of data.
#include <stdio.h>
typedef enum Format_
{
/* Add/remove formats as needed. */
SIGNED_DECIMAL_INT,
UNSIGNED_DECIMAL_INT,
DECIMAL_FLOATING_POINT,
STRING,
POINTER_ADDRESS,
NUM_SUPPORTED_FORMATS
} Format;
static const char* formatStrings[NUM_SUPPORTED_FORMATS] =
{
"%d\n", /* Add more complex format strings if needed. */
"%u\n",
"%f\n",
"%s\n",
"%p\n"
};
typedef struct Wrapper_
{
Format format;
float data;
} Wrapper;
void printData(const Wrapper *const wrapper)
{
printf(formatStrings[wrapper->format], wrapper->data);
}
int main(void)
{
Wrapper wrapper;
wrapper.format = DECIMAL_FLOATING_POINT;
wrapper.data = 12.345f;
/* Prints 12.345000 */
printData(&wrapper);
return 0;
}
I know you can return a character string from a normal function in C as in this code
#include <stdio.h>
char* returnstring(char *pointer) {
pointer="dog";
return pointer;
}
int main(void)
{
char *dog = NULL;
printf("%s\n", returnstring(dog));
}
However, I can't find a way to be able to return character strings in #define functions, as in this code
#include <stdio.h>
#define returnstring(pointer) { \
pointer="dog"; \
return pointer; \
}
int main(void)
{
char *dog = NULL;
printf("%s\n", returnstring(dog));
}
I know that there are workarounds(like using the first program). I just want to know if it is possible
Thinking about a "#define function" is, IMO, the wrong way to approach this.
#define is a blunt instrument which amounts to a text find/replace. It knows little to nothing about C++ as a language, and the replace is done before any of your real code is even looked at.
What you have written isn't a function in its own right, it is a piece of text that looks like one, and it put in where you have written the alias.
If you want to #define what you just did, that's fine (I didn't check your example specifically, but in general, using #define for a function call and substituting the arguments is possible), but think twice before doing so unless you have an amazing reason. And then think again until you decide not to do it.
You can't "return" from a macro. Your best (ugh... arguably the "best", but anyway) bet is to formulate your macro in such a way that it evaluates to the expression you want to be the result. For example:
#define returnstring(ptr) ((ptr) = "hello world")
const char *p;
printf("%s\n", returnstring(p));
If you have multiple expression statements, you can separate them using the horrible comma operator:
#define even_more_dangerous(ptr) (foo(), bar(), (ptr) = "hello world")
If you are using GCC or a compatible compiler, you can also take advantage of a GNU extension called "statement expressions" so as to embed whole (non-expression) statements into your macro:
#define this_should_be_a_function(ptr) ({ \
if (foo) { \
bar(); \
} else { \
for (int i = 0; i < baz(); i++) { \
quirk(); \
} \
} \
ptr[0]; // last statement must be an expression statement \
})
But if you get to this point, you could really just write a proper function as well.
You don't return anything from a #defined macro. Roughly speaking, the C preprocessor replaces the macro call with the text of the macro body, with arguments textually substituted into their positions. If you want a macro to assign a pointer to "dog" and evaluate to the pointer, you can do this:
#define dogpointer(p) ((p)="dog")
The thing is returnstring as a macro does not do what it says; it also assigns the value to the parameter. The function does as it says, even if it (somewhat oddly) uses its parameter as a temporary variable.
The function is equivalent to:
char* returnstring(char *ignored) {
return "dog";
}
The function macro is much the same as:
#define returnstring(pointer) pointer = "dog"
Which begs the question, why not call it assign_string?
Or why not just have:
#define dogString "dog"
And write:
int main(void)
{
char *dog = NULL;
printf("%s\n", dog = dogString);
}
The function for assignString is:
char* assignstring(char **target{
*target= "dog";
return *target;
}
You can then have a macro:
assign_string_macro(pointer) assignstring(&pointer)
Ultimately if you want to "return character strings in #define functions", then all you need is:
#define returnstring(ignored) "dog"