Having this #define PRINTF(...) printf(__VA_ARGS__) I want to create a macro that calls PRINTF but that adds prefix to the printed string, for example:
#define PRINTF_P(<args>) PRINTF(<whatever>)
// let's suppose that the desired prefix is 'prefix - '
PRINTF_P("Hello world\n");
PRINTF_P("Hello world, num = %d\n", 25);
// Result:
prefix - Hello world
prefix - Hello world, num = 20
How can I do this?
What I have tried
The following works for calls like PRINTF_P("string with argument %d\n", arg), but it doesn't for calls like `PRINTF_P("string with no argument\n");
#include <stdio.h>
#include <stdarg.h>
#define PRINTF(...) printf(__VA_ARGS__)
#define A(fmt, ...) fmt
#define B(fmt, ...) __VA_ARGS__
#define PRINTF_P(...) printf( "prefix - " A(__VA_ARGS__), B(__VA_ARGS__))
int main(void)
{
PRINTF_P("No number\n"); // This fails
PRINTF_P("Number = %d\n", 20); // This works
return 0;
}
EDIT
I'm referring only to the case of string literals, not char *.
It is as easy as:
#include <stdio.h>
#include <stdarg.h>
#define PRINTF(...) printf(__VA_ARGS__)
#define PRINTF_P(...) printf( "prefix " __VA_ARGS__)
int main(void)
{
PRINTF("No number\n");
PRINTF("Number = %d\n", 20);
PRINTF_P("No number\n");
PRINTF_P("Number = %d\n", 20);
return 0;
}
I'm not sure why you should use a macro at all.
Just write an encapsulating function using vprintf and variable args.
IDEOne Link
#include <stdarg.h>
int prefix_printf(const char* fmt, ...)
{
printf("prefix "); // Print desired Prefix
va_list args; // Declare a variable for the "..."
va_start(args, fmt); // Initialize the args as everything after parameter "fmt"
int result = vprintf(fmt, args); // Variant of printf that accepts args instead of ...
va_end(args); // Clean up the args
return result; // Return the same value printf would've returned
}
int main(void) {
prefix_printf("No number\n");
prefix_printf("Number = %d\n", 20);
return 0;
}
Result:
Success #stdin #stdout 0.01s 5536KB
prefix No number
prefix Number = 20
how to create a function with variable pointers parameters that
take any number of pointer and print it such as :
print("hello ","world ");
print("i'm ","adil"," blah "," blah");
result like that :
$ ./myprogramme
hello word im adil blah blah
I found stdarg.h but i don't know how to make it ?
In C, you can create a variadic function using stdarg.h. Example from Wikipedia link,
#include <stdarg.h>
double average(int count, ...)
{
va_list ap;
int j;
double sum = 0;
va_start(ap, count); /* Requires the last fixed parameter
(to get the address) */
for (j = 0; j < count; j++) {
sum += va_arg(ap, double); /* Increments ap to the next argument. */
}
va_end(ap);
return sum / count;
}
This is almost what you wanted, but it needed a NULL terminator
#include <stdio.h>
#include <stdarg.h>
void print (char *first, ...)
{
va_list argptr;
char *next;
va_start (argptr, first);
next = first;
while (next) {
printf ("%s", next);
next = va_arg(argptr, char*);
}
va_end (argptr);
}
int main()
{
print("hello ","world ", NULL);
print("i'm ","adil"," blah "," blah", NULL);
return 0;
}
But by adding a different argument, there's an easy answer anyway
printf("%s%s", "hello ","world ");
printf("%s%s%s%s", "i'm ","adil"," blah "," blah");
I have a program which does concatenation.
its like char *testConc(int a,..)
Where a indicates number of arguments are being passed for concatenation.
As legth keeps on changing is there is anything like constructor overloading in C
or any simple syntax which implements the functionality
Yes, there are varadic functions
#include <stdio.h>
#include <stdarg.h>
/* print all non-negative args one at a time;
all args are assumed to be of int type */
void printargs(int arg1, ...)
{
va_list ap;
int i;
va_start(ap, arg1);
for (i = arg1; i >= 0; i = va_arg(ap, int))
printf("%d ", i);
va_end(ap);
putchar('\n');
}
int main(void)
{
printargs(5, 2, 14, 84, 97, 15, 24, 48, -1);
printargs(84, 51, -1);
printargs(-1);
printargs(1, -1);
return 0;
}
C does not have function overloading capabilities. The syntax you have is called a variadic function, which can be used to perform what you asked.
The textConc function would look something like this:
char *textConc(int argc, ...)
{
va_list args;
char *str = NULL;
size_t len = 0;
va_start(args, argc);
while (argc--)
{
/* next string */
const char *temp = va_arg(args, const char *);
size_t size = strlen(temp);
/* make room and copy over */
str = realloc(str, len+size+1);
memcpy(str+len, temp, size+1);
/* new length */
len += size;
}
va_end(args);
return str;
}
int main(int argc, char **argv)
{
char *example = textConc(4, "Hello", "All", "good", "morning");
puts(example);
free(example);
return 0;
}
If you use GCC, we can fake overloading completely, using a little help of macros.
Rename textConc to textConcN and use the following macros:
#define ARGCOUNT(...) (sizeof((const char *[]){__VA_ARGS__})/sizeof(const char *))
#define textConc(...) textConcN(ARGCOUNT(__VA_ARGS__), __VA_ARGS__)
int main(int argc, char **argv)
{
/* notice, no more need for the number of arguments */
char *example = textConc("Hello", "All", "good", "morning");
puts(example);
free(example);
return 0;
}
Functions can't be overloaded in C.
You could rewrite your function as char *testConc(const char *s, ...), where you mark the end of the list with NULL:
testConc("foo", "bar", "baz", "quux", (char *)0);
This makes adding changing the number of actual arguments easier. If you have a C99 compiler, you can even write a wrapping macro that adds the NULL for you:
#define TESTCONC(...) testConc(__VA_ARGS__, (char *)0)
I want to write this to only 1 line:
fprintf(stdout, "RCPT TO: <%s>\r\n", argv[argc-1]);
fprintf(sockfd, "RCPT TO: <%s>\r\n", argv[argc-1]);
so i want to send the same string to stdout and to my open socket. How can I do this?
With
#include <stdarg.h>
int fprintf_both(FILE *a, FILE *b, const char *fmt, ...)
{
FILE *f[2];
const int n = sizeof(f) / sizeof(f[0]);
int i;
int sum = 0;
f[0] = a;
f[1] = b;
for (i = 0; i < n; i++) {
va_list ap;
int bytes;
va_start(ap, fmt);
bytes = vfprintf(f[i], fmt, ap);
va_end(ap);
if (bytes < 0)
return bytes;
else
sum += bytes;
}
return sum;
}
you can
fprintf_both(stdout, sockfd, "RCPT TO: <%s>\r\n", argv[argc-1]);
Not unless you want to write your own function that takes two File* and varargs, and calls fprintf twice.
I guess you want to do this to put it inside something like a while loop condition? You might like the C comma operator, e.g.
while ( f1(), f2() ) { //bla }
The comma causes f1() to be executed, it's return value discarded, followed by f2() and the its return value kept. (i.e. f2() should return an int or bool and f1() doesn't matter)
Say I have a C function which takes a variable number of arguments: How can I call another function which expects a variable number of arguments from inside of it, passing all the arguments that got into the first function?
Example:
void format_string(char *fmt, ...);
void debug_print(int dbg_lvl, char *fmt, ...) {
format_string(fmt, /* how do I pass all the arguments from '...'? */);
fprintf(stdout, fmt);
}
To pass the ellipses on, you initialize a va_list as usual and simply pass it to your second function. You don't use va_arg(). Specifically;
void format_string(char *fmt,va_list argptr, char *formatted_string);
void debug_print(int dbg_lvl, char *fmt, ...)
{
char formatted_string[MAX_FMT_SIZE];
va_list argptr;
va_start(argptr,fmt);
format_string(fmt, argptr, formatted_string);
va_end(argptr);
fprintf(stdout, "%s",formatted_string);
}
There's no way of calling (eg) printf without knowing how many arguments you're passing to it, unless you want to get into naughty and non-portable tricks.
The generally used solution is to always provide an alternate form of vararg functions, so printf has vprintf which takes a va_list in place of the .... The ... versions are just wrappers around the va_list versions.
Variadic Functions can be dangerous. Here's a safer trick:
void func(type* values) {
while(*values) {
x = *values++;
/* do whatever with x */
}
}
func((type[]){val1,val2,val3,val4,0});
In magnificent C++11 you could use variadic templates:
template <typename... Ts>
void format_string(char *fmt, Ts ... ts) {}
template <typename... Ts>
void debug_print(int dbg_lvl, char *fmt, Ts... ts)
{
format_string(fmt, ts...);
}
Though you can solve passing the formatter by storing it in local buffer first, but that needs stack and can sometime be issue to deal with. I tried following and it seems to work fine.
#include <stdarg.h>
#include <stdio.h>
void print(char const* fmt, ...)
{
va_list arg;
va_start(arg, fmt);
vprintf(fmt, arg);
va_end(arg);
}
void printFormatted(char const* fmt, va_list arg)
{
vprintf(fmt, arg);
}
void showLog(int mdl, char const* type, ...)
{
print("\nMDL: %d, TYPE: %s", mdl, type);
va_list arg;
va_start(arg, type);
char const* fmt = va_arg(arg, char const*);
printFormatted(fmt, arg);
va_end(arg);
}
int main()
{
int x = 3, y = 6;
showLog(1, "INF, ", "Value = %d, %d Looks Good! %s", x, y, "Infact Awesome!!");
showLog(1, "ERR");
}
Hope this helps.
You can try macro also.
#define NONE 0x00
#define DBG 0x1F
#define INFO 0x0F
#define ERR 0x07
#define EMR 0x03
#define CRIT 0x01
#define DEBUG_LEVEL ERR
#define WHERESTR "[FILE : %s, FUNC : %s, LINE : %d]: "
#define WHEREARG __FILE__,__func__,__LINE__
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define DEBUG_PRINT(X, _fmt, ...) if((DEBUG_LEVEL & X) == X) \
DEBUG(WHERESTR _fmt, WHEREARG,__VA_ARGS__)
int main()
{
int x=10;
DEBUG_PRINT(DBG, "i am x %d\n", x);
return 0;
}
You can use inline assembly for the function call. (in this code I assume the arguments are characters).
void format_string(char *fmt, ...);
void debug_print(int dbg_level, int numOfArgs, char *fmt, ...)
{
va_list argumentsToPass;
va_start(argumentsToPass, fmt);
char *list = new char[numOfArgs];
for(int n = 0; n < numOfArgs; n++)
list[n] = va_arg(argumentsToPass, char);
va_end(argumentsToPass);
for(int n = numOfArgs - 1; n >= 0; n--)
{
char next;
next = list[n];
__asm push next;
}
__asm push fmt;
__asm call format_string;
fprintf(stdout, fmt);
}
Ross' solution cleaned-up a bit. Only works if all args are pointers. Also language implementation must support eliding of previous comma if __VA_ARGS__ is empty (both Visual Studio C++ and GCC do).
// pass number of arguments version
#define callVardicMethodSafely(...) {value_t *args[] = {NULL, __VA_ARGS__}; _actualFunction(args+1,sizeof(args) / sizeof(*args) - 1);}
// NULL terminated array version
#define callVardicMethodSafely(...) {value_t *args[] = {NULL, __VA_ARGS__, NULL}; _actualFunction(args+1);}
Short answer
/// logs all messages below this level, level 0 turns off LOG
#ifndef LOG_LEVEL
#define LOG_LEVEL 5 // 0:off, 1:error, 2:warning, 3: info, 4: debug, 5:verbose
#endif
#define _LOG_FORMAT_SHORT(letter, format) "[" #letter "]: " format "\n"
/// short log
#define log_s(level, format, ...) \
if (level <= LOG_LEVEL) \
printf(_LOG_FORMAT_SHORT(level, format), ##__VA_ARGS__)
usage
log_s(1, "fatal error occurred");
log_s(3, "x=%d and name=%s",2, "ali");
output
[1]: fatal error occurred
[3]: x=2 and name=ali
log with file and line number
const char* _getFileName(const char* path)
{
size_t i = 0;
size_t pos = 0;
char* p = (char*)path;
while (*p) {
i++;
if (*p == '/' || *p == '\\') {
pos = i;
}
p++;
}
return path + pos;
}
#define _LOG_FORMAT(letter, format) \
"[" #letter "][%s:%u] %s(): " format "\n", _getFileName(__FILE__), __LINE__, __FUNCTION__
#ifndef LOG_LEVEL
#define LOG_LEVEL 5 // 0:off, 1:error, 2:warning, 3: info, 4: debug, 5:verbose
#endif
/// long log
#define log_l(level, format, ...) \
if (level <= LOG_LEVEL) \
printf(_LOG_FORMAT(level, format), ##__VA_ARGS__)
usage
log_s(1, "fatal error occurred");
log_s(3, "x=%d and name=%s",2, "ali");
output
[1][test.cpp:97] main(): fatal error occurred
[3][test.cpp:98] main(): x=2 and name=ali
custom print function
you can write custom print function and pass ... args to it and it is also possible to combine this with methods above. source from here
int print_custom(const char* format, ...)
{
static char loc_buf[64];
char* temp = loc_buf;
int len;
va_list arg;
va_list copy;
va_start(arg, format);
va_copy(copy, arg);
len = vsnprintf(NULL, 0, format, arg);
va_end(copy);
if (len >= sizeof(loc_buf)) {
temp = (char*)malloc(len + 1);
if (temp == NULL) {
return 0;
}
}
vsnprintf(temp, len + 1, format, arg);
printf(temp); // replace with any print function you want
va_end(arg);
if (len >= sizeof(loc_buf)) {
free(temp);
}
return len;
}
Let's say you have a typical variadic function you've written. Because at least one argument is required before the variadic one ..., you have to always write an extra argument in usage.
Or do you?
If you wrap your variadic function in a macro, you need no preceding arg. Consider this example:
#define LOGI(...)
((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
This is obviously far more convenient, since you needn't specify the initial argument every time.
I'm unsure if this works for all compilers, but it has worked so far for me.
void inner_func(int &i)
{
va_list vars;
va_start(vars, i);
int j = va_arg(vars);
va_end(vars); // Generally useless, but should be included.
}
void func(int i, ...)
{
inner_func(i);
}
You can add the ... to inner_func() if you want, but you don't need it. It works because va_start uses the address of the given variable as the start point. In this case, we are giving it a reference to a variable in func(). So it uses that address and reads the variables after that on the stack. The inner_func() function is reading from the stack address of func(). So it only works if both functions use the same stack segment.
The va_start and va_arg macros will generally work if you give them any var as a starting point. So if you want you can pass pointers to other functions and use those too. You can make your own macros easily enough. All the macros do is typecast memory addresses. However making them work for all the compilers and calling conventions is annoying. So it's generally easier to use the ones that come with the compiler.