I am learning C. After completing the common core part. I found this unique program which will allow the user to create his own format specifier which will use "%b" as format specifier to convert a integer directly into binary.
I want to know more about this code.
How it works and how i can modify it.
Please Help me.

#include <stdarg.h>
void MyPrintf( char *fmt, ... )
{
va_list aptr; /* Points to each unscanned arg in turn */
char *p, *sval, str[17];
int ival;
double dval;
va_start( aptr, fmt ); /* Initialize the argument pointer. */
/* Retrieve each argument in the variable list... */
for( p=fmt; *p ; ++p )
if( *p=='%' )
switch( * ++p )
{
case 'd':
ival = va_arg( aptr, int );
printf( "%d", ival );
break;
case 'f':
dval = va_arg( aptr, double );
printf( "%f", dval );
break;
case 's':
for( sval=va_arg(aptr, char*); *sval; ++sval )
putchar( *sval );
break;
case 'b': /* for binary */
ival = va_arg(aptr, int); /* Get it as integer */
/* radix should be 2 for binary in itoa... */
itoa( ival, str, 2 );
31
32 A to Z of C
for( sval=str; *sval; ++sval )
putchar(*sval);
break;
default:
putchar(*p);
}
else
putchar( *p );
va_end( aptr ); /* Clean up when done */
} /*--MyPrintf( )----------*/
int main( void )
{
MyPrintf( "7 in binary is %b \n", 7 );
return(0);
} /*--main( )-----*/

I found this unique program which will allow the user to create his own format specifier which will use "%b" as format specifier to convert a integer directly into binary.

Hardly unique, it's just another naive implementation of printf() that adds specifiers at the author's whim. Not that it isn't useful for learning how variable length argument lists are implemented, of course.

I want to know more about this code.

What do you want to know? I've implemented printf() for real (as in fully conforming to the C standard), so I can probably answer any questions you have about how it works under the hood.

However, I'm disinclined to give you a lecture about how the code works and why, so I'll kindly request that you ask some specific questions for me to answer.

Edited 4 Years Ago by deceptikon

va_arg( aptr, double )

where does the data type definitions are stored and can i modify them?

Can't read the code because of lack of formatting. Try again.

#include <stdarg.h>


void MyPrintf( char *fmt, ... )
{
va_list aptr; /* Points to each unscanned arg in turn */
char *p, *sval, str[17];
int ival;
double dval;
va_start( aptr, fmt ); /* Initialize the argument pointer. */

/* Retrieve each argument in the variable list... */
for( p=fmt; *p ; ++p )
   if( *p=='%' )
    switch( * ++p )
    {   
    case 'd':
    ival = va_arg( aptr, int );
    printf( "%d", ival );
    break;

    case 'f':
    dval = va_arg( aptr, double );
    printf( "%f", dval );
    break;

    case 's':
    for( sval=va_arg(aptr, char*); *sval; ++sval )
    putchar( *sval );
    break;

    case 'b': /* for binary */
    ival = va_arg(aptr, int); /* Get it as integer */
    /* radix should be 2 for binary in itoa... */
    itoa( ival, str, 2 );
    for( sval=str; *sval; ++sval )
    putchar(*sval);
    break;

    default:
    putchar(*p);
    }
   else
   putchar( *p );
   va_end( aptr ); /* Clean up when done */
}
 /*--MyPrintf( )----------*/

int main( void )
{
MyPrintf( "7 in binary is %b \n", 7 );
return(0);
} /*--main( )-----*/

va_arg( aptr, double )
where does the data type definitions are stored and can i modify them?

I don't understand the question. va_arg() takes the next value from the variable argument list and interprets it as the type you pass for the second argument. So in va_arg( aptr, double ), the next argument is interpreted as a value of type double and "returned" for your use.

Let's simplify a bit. Here's a bare bones variable length argument function. It requires that all variable arguments be of type int:

#include <stdarg.h>
#include <stdio.h>

void foo(int n, ...)
{
    va_list args;
    int i;

    va_start(args, n); /* Start pulling varargs after n */

    for (i = 0; i < n; ++i)
        printf("Arg #%d: %d\n", i + 1, va_arg(args, int));

    va_end(args);
}

int main(void)
{
    foo (5, 11, 22, 33, 44, 55);

    return 0;
}

Edited 4 Years Ago by deceptikon

I want to ask that as I use int, float etc datatypes in coding can i modify them.

I want to ask that as I use int, float etc datatypes in coding can i modify them.

I still don't understand. You can choose an existing type to interpret the argument as, and it gives you a value (or invokes undefined behavior if you ask for an incompatible type). From there you can do whatever you want with the value.

As in the MyPrintf() example, you can use something like a format string to figure out what type to use in va_arg(), because that type is hard coded.

I want to ask that as I use int, float etc datatypes in coding can i modify them.

int a=20;       //integer  
bnry b=100110; //binary

As above i want to create a datatype of my own which will accept binary number as its type. So can i create this?? And can i modify existing types such as int?

So can i create this??

Not as such, no. The best you can do without massive amounts of preprocessing (whch C++ started out as, on a side note) is defining your own type as a structure and creating functions to work with it.

And can i modify existing types such as int?

No, and I'm truly thankful for that because nobody in their right mind would alter the syntax or behavior of built-in types.

For future study, read, 'The lil Black Book of Computer Viruses', and in relation to what you are wanting, I say skip this and look towards strait assembly and logic gates. Good luck!

This article has been dead for over six months. Start a new discussion instead.