How can I create a wrapper for scanf function in C? - c

The problem I have is as follows:
I need to create a function in C, using the standard libraries. This function should take parameters just like scanf() function in c and should call scanf(parameters) inside it.

You could use vscanf(3):
int my_scanf(const char *fmt, ...)
{
int rc;
va_list args;
va_start(args, fmt);
rc = vscanf(fmt, args);
va_end(args);
return rc;
}

Related

Using Sprintf With Arguments Just Like İn Vprintf [duplicate]

This question already has an answer here:
C - Variable Argument with Sprintf?
(1 answer)
Closed 2 years ago.
I try to achieve same thing in vprintf function using sprintf to write into buffer, however I can not do it. What is my mistake?
#include <stdio.h>
#include <stdarg.h>
char latestPrint[1000];
int currentPositionPrint=0;
void WriteFrmtd(char *format, ...) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
void WriteToPrint(char *format, ...) {
va_list args;
va_start(args, format);
currentPositionPrint+=sprintf(currentPositionPrint+latestPrint , format, args);
va_end(args);
}
int main () {
WriteFrmtd("%d variable argument\n", 1);
WriteFrmtd("%d variable %s\n", 2, "argumentsqweqweqweqwe");
WriteToPrint("%d variable %s\n", 2, "argumentsqweqweqweqwe");
printf("%s",latestPrint);
return(0);
}
Output:
1 variable argument
2 variable argumentsqweqweqweqwe
1698242904 variable 1698242904 variable
You can use vsprintf (same as vprintf but using an array as output instead of stdout):
void WriteToPrint(char *format, ...)
{
va_list args;
va_start(args, format);
currentPositionPrint += vsprintf(latestPrint + currentPositionPrint, format, args);
va_end(args);
}
You can't use sprintf with variable arguments. You need to use vsprintf instead:
Change:
currentPositionPrint += sprintf(currentPositionPrint+latestPrint , format, args);
to:
currentPositionPrint += vsprintf(currentPositionPrint+latestPrint , format, args);
Free hint: use spaces between operators: foo += bar is more readable than foo+=bar.

Variable argument passing in C to printf / vsprintf

I am trying to pass variable arguments that I get to another function I call.
I had written a sample code to test this.
Why is my_printf working but not my2_printf in below code?
#include <stdio.h>
#include <stdarg.h>
my2_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
printf(fmt, ap);
va_end(ap);
}
my_printf(const char *fmt, ...)
{
va_list ab;
va_start(ab, fmt);
vfprintf(stdout, fmt, ab);
va_end(ab);
}
main()
{
int i = 5;
my_printf("This is a test %d => %s\n", i, "done");
my2_printf("This is a test %d => %s\n", i, "done");
}
Output I get is as below:
This is a test 5 => done
This is a test -171084944 =>
Because there's variant of printf that expects a va_list argument. If you have a va_list you must use the functions with the v prefix, such as vprintf.
The call to printf leads to undefined behavior.

Duplicating a function with a new name

I am making a C library that creates a print function, which basically executes printf. Because of this, I wish to create a duplicate of printf from glibc, but with the name print. How can I duplicate this function without duplicating all of it's code?
(I found the code here but don't understand how to duplicate it in my library, or if it is legal to do so.)
There you go:
#include <stdarg.h>
void println(const char* format,...)
{
va_list args;
va_start(args,format);
vprintf(format,args);
printf("\n");
va_end(args);
}
You can use a variadic macro:
#define println(...) (printf(__VA_ARGS__), (void) puts(""))
You can either use a Macro:
#define print printf
or define a wrapper function
int print( char *fmt, ... )
{
va_list ap;
int n;
va_start(ap, fmt);
n = vprintf(fmt, ap);
va_end(ap);
return n;
}

How to print both to stdout and file in C

I read this topic, but his problem maybe different from mine
Writing to both stdout & a file
I want to write a function, that function need to print out to both stdout and a file. My C program gets user input by scanf.
I intend to write a function like printf but I don't really know how:
I tried this, but it only can work with "pure" string, can't convert %d, %.*lf (my print function only need two conversions)
void dupPrint(FILE *fp,char *string)
{
printf("%s",string);
fprintf(fp,"%s",string);
return;
}
I tried dup2 and freopen but they didn't work for me.
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
int i;
int file = open("input3.txt", O_APPEND | O_WRONLY);
if(file < 0) return 1;
if(dup2(file,1) < 0) return 1;
printf("Redirect to file!\n");
printf("enter i : ");
scanf("%d",&i);
return 0;
}
This dup2() tutorial only print to file.
I also tried tee, but may be it not work because I have to get input from user (if work, it's not "fair" because tee isn't in my program).
I think implement a printf-like will solved problem but I don't know how to convert .*lf
(print out double with user-enter precision)
#include <stdio.h>
#include <stdarg.h>
void dupPrint(FILE *fp,char *fmt, ...)
{
va_list ap;
char *p, *sval;
int ival;
double dval;
va_start (ap, fmt); //make ap point to 1st unnamed arg
for(p = fmt; *p; p++)
{
if (*p != '%') {
putchar(*p);
continue;
}
switch (*++p) {
case 'd':
ival = va_arg(ap, int);
printf("%d", ival);
break;
case '.*lf' //?????
}
}
}
Can anyone suggest a solution for my problem?
Fortunately, you don't need to. You just want to use the v variants of printf and fprintf that take a va_list instead of your passing arguments directly:
void tee(FILE *f, char const *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
va_start(ap, fmt);
vfprintf(f, fmt, ap);
va_end(ap);
}
You can implement your dupPrint function using vfprintf and va_list/ va_start / va_end.
in the mid-layer:
#define DUPPRINT(fp, fmt...) do {printf(fmt);fprintf(fp,fmt);} while(0)
in your app code:
...
DUPPRINT(fd, "%s:%d\n", val_name, val_v);
...
Use a variadic function and vprintf!
void dupPrint(FILE *fp,char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
va_start(ap, fmt);
vfprintf(fp, fmt, ap);
va_end(ap);
}
Optionally, implement vdupPrint, have dupPrint call vdupPrint, and use va_copy (if C99 is available) to duplicate the va_list instead of the stop-and-restart method I used. (If va_copy is not available to you, you'll have to start two separate va_lists and pass them both to vdupPrint, which is a sub-optimal solution but will work for C89 safely.)

C syntax to create function foo(...)

Sorry for the simple question, but how could I create the C-function with undefined number of parameters such as
int printf ( const char * format, ... ).
I would like to create function to use it as wrapper for printk:
void my_printk( const char * format, ...)
{
printk("my log:");
printk(format, ...);
printk("\n");
}
Thanks
You have to convert the args to a va_list before you can pass it to another function. Then you can pass it to the 'v' version of the function.
So you can do:
void my_printk( const char * format, ...)
{
va_list ap;
va_start(ap, format);
printk("my log:");
vprintk(format, ap);
printk("\n");
va_end(ap);
}
Most of the time, any function like this will provide a 'v' version, and yours should too:
void my_vprintk( const char * format, va_list ap)
{
printk("my log:");
vprintk(format, ap);
printk("\n");
}
void my_printk( const char * format, ...)
{
va_list ap;
va_start(ap, format);
my_vprintk(format, ap);
va_end(ap);
}
You're close. Have a look here: http://publications.gbdirect.co.uk/c_book/chapter9/stdarg.html
int f(int, ... );
int f(int, ... ) {
.
.
.
}
int g() {
f(1,2,3);
}

Resources