问题
Actually I am trying to write my own printf()
in C by using varags. But I am not getting the correct solution for this. Can anyone help me out?
回答1:
Before implementation of printf( ) function we have to deal with unusual problem which is variable arguments. As we know that printf can take many arguments besides string. So we have to use a standard library called stdarg.h to handle this variable argument problem. In this implementation context, we don’t need learn whole stdarg.h library because we use some macro functions of these library which is understandable directly by our C program.
Here is the code source which explain nice and fast
#include<stdio.h>
#include<stdarg.h>
void Myprintf(char *,...); //Our printf function
char* convert(unsigned int, int); //Convert integer number into octal, hex, etc.
int main()
{
Myprintf(" WWW.FIRMCODES.COM \n %d", 9);
return 0;
}
void Myprintf(char* format,...)
{
char *traverse;
unsigned int i;
char *s;
//Module 1: Initializing Myprintf's arguments
va_list arg;
va_start(arg, format);
for(traverse = format; *traverse != '\0'; traverse++)
{
while( *traverse != '%' )
{
putchar(*traverse);
traverse++;
}
traverse++;
//Module 2: Fetching and executing arguments
switch(*traverse)
{
case 'c' : i = va_arg(arg,int); //Fetch char argument
putchar(i);
break;
case 'd' : i = va_arg(arg,int); //Fetch Decimal/Integer argument
if(i<0)
{
i = -i;
putchar('-');
}
puts(convert(i,10));
break;
case 'o': i = va_arg(arg,unsigned int); //Fetch Octal representation
puts(convert(i,8));
break;
case 's': s = va_arg(arg,char *); //Fetch string
puts(s);
break;
case 'x': i = va_arg(arg,unsigned int); //Fetch Hexadecimal representation
puts(convert(i,16));
break;
}
}
//Module 3: Closing argument list to necessary clean-up
va_end(arg);
}
char *convert(unsigned int num, int base)
{
static char Representation[]= "0123456789ABCDEF";
static char buffer[50];
char *ptr;
ptr = &buffer[49];
*ptr = '\0';
do
{
*--ptr = Representation[num%base];
num /= base;
}while(num != 0);
return(ptr);
}
回答2:
If you have some time and are really curious you could study the GNU libc's version: See printf, which in turn uses vprintf, which uses vfprintf
回答3:
Linux va_start(3) man page gives very good example of writing such functions (much more simpler but in general all the major bricks are there). Also you could examine almost any libstdc implementation.
回答4:
There are at least two books with good explanations of how a printf()
-like formatting function can be written (and complete working examples):
- Plauger, 'The Standard C Library'
- Hanson, 'C Interfaces and Implementations'
回答5:
This answer may help you to understand how to write variadic functions. Note, no error / bounds checking is done, no attributes are set to tell the compiler what kind of arguments might be suitable, no benefit over just using printf() is achieved.
It may or may not be the example you are looking for.
The relevant snippet (expanded a bit here):
#include <stdarg.h>
void _printf(FILE *out, va_list ap)
{
vfprintf(out, fmt, ap);
}
void printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
_printf(stdout, ap);
va_end(ap);
}
Note: making these return the correct type (signed integer) is left as an exercise for the reader. This looks a lot like homework to me, I'm just trying to get you past any sticking point of using va_start and va_end, plus showing that a va_list can be passed to helper functions to avoid duplicating code in so many implementations of almost the same thing.
I strongly advise looking at the BSD (or even glibc) printf sub system implementation. You could also look at uclibc, dietlibc, etc ..
来源:https://stackoverflow.com/questions/1735236/how-to-write-my-own-printf-in-c