how to print variable number of arguments? (ANSI C)

125 Views Asked by At

I'm trying to compare the bits of variable number of arguments and print their value. but I'm getting garbage. what am I doing wrong?

My Code:

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

void and_bits(unsigned int num, ...)
{
unsigned int i = 0;
/* result is 11111111 in binary*/
unsigned int result = 255;

va_list arglist;
va_start(arglist, num);

/* this loop takes each argument, and apply AND bitwise operator to the next argument*/
for (i = 0; i < num; i++)
{
    
    /* bitwise AND operator */
    result &= va_arg(arglist,unsigned int);
    printf("%u, ",va_arg(arglist,unsigned int));
}
va_end(arglist);
printf("\nthe return value: base 10 = %u\t", result);
printf("base 16 = %x\n", result);
return;
}

int main(void)
{
and_bits(7,2,3);
return 0;
}

The Output:

3, 0, 0, 1987831328, 0, 3742925664, 3742924928,
the return value: base 10 = 0   base 16 = 0
1

There are 1 best solutions below

1
On

So, you have two problems. The first is covered in comments, but essentially you're not calling and_bits correct. The first argument should be a count.

But you have a bigger problem, right here:

for (i = 0; i < num; i++)
{
    
    /* bitwise AND operator */
    result &= va_arg(arglist,unsigned int);
    printf("%u, ",va_arg(arglist,unsigned int));
}

Every time you call va_arg(), you advance the argument pointer by one. So assuming you've called and_bits(3, 7, 2, 3), then on the first iteration of the loop:

  1. You call va_arg(), which returns the value 7, and you set result to result & 7.

  2. Then on the next line, you call va_arg(), which returns 2, so you print that out.

Then in the next iteration of the loop:

  1. You call va_arg(), which returns 3, and set result to result & 3.

  2. You call va_arg() again, but you've already consumed three arguments so now you're reading beyond the argument list and you get undefined results.

You're going to go through the loop one more time, and at this point all values returned by va_arg() will be invalid.

You should modify the loop so that it only calls va_arg() once:

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

void and_bits(unsigned int num, ...)
{
unsigned int i = 0;
/* result is 11111111 in binary*/
unsigned int result = 255;

va_list arglist;
va_start(arglist, num);

/* this loop takes each argument, and apply AND bitwise operator to the next argument*/
for (i = 0; i < num; i++)
{
    
    /* bitwise AND operator */
    unsigned int val = va_arg(arglist,unsigned int);
    result &= val;
    printf("%u: val=%u, result=%u\n", i, val, result);
}
va_end(arglist);
printf("\nthe return value: base 10 = %u\t", result);
printf("base 16 = %x\n", result);
return;
}

int main(void)
{
and_bits(3, 7,2,3);
return 0;
}

Which produces as output:

0: val=7, result=7
1: val=2, result=2
2: val=3, result=2

the return value: base 10 = 2   base 16 = 2