So, I know the question sounds strange but I don't really know how to phrase it better. I'll try to explain: I'm writing my own version of printf, this is the code I have so far:
Code:
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
void print(char *, ...);
char *convert(unsigned int, int);
char *to_lower(unsigned int, int);
unsigned int count_digits(unsigned int);
int main()
{
char str[12]="World";
char c='A';
int n = 5, x= 1011, y = 12, z = 5, t = 10;
print("Hello s c |%s| |%c| 5 |%d| 5 some random %X %x %b %o words %4d\n", str, c, n, x, y, z, t, z);
}
void print(char *format, ...)
{
int num, precision = 0;
va_list lst;
va_start(lst, format);
while(*format != '\0')
{
if(*format != '%')
{
putchar(*format);
format++;
continue;
}
format++;
if(isdigit(*format))
{
precision = atoi(format);
format++;
continue;
}
//format++;
switch(*format)
{
case 'c':
putchar(va_arg(lst, int));
break;
case 'd':
num = (va_arg(lst, int));
if(num > 0)
{
fputs(convert(num,10), stdout);
}
else
{
num = -num;
putchar('-');
fputs(convert(num,10), stdout);
}
break;
case 's':
fputs(va_arg(lst, char *), stdout);
break;
case 'X':
num = va_arg(lst, int);
fputs(convert(num,16), stdout);
break;
case 'x':
num = va_arg(lst, int);
fputs(to_lower(num,16), stdout);
break;
case 'b':
num = va_arg(lst, int);
fputs(convert(num,2), stdout);
break;
case 'o':
num = va_arg(lst, int);
fputs(convert(num,8), stdout);
break;
}
format++;
}
va_end(lst);
}
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);
}
char *to_lower(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);
}
unsigned int count_digits(unsigned int n)
{
unsigned int counter = 0, lastDigit;
while(n != 0)
{
lastDigit = n%10;
n = n/10;
counter++;
}
return counter;
}
Output:
Hello s c |World| |A| 5 |5| 5 some random 3F3 c 101 12 words d
(As you can see it's only printing 'd' from '%4d' because I've extracted the 4). The program is working fine so far but I have a problem. I'm trying to implement the functionality where if we write:
%nd, where n is a natural number, an integer of n characters will be printed (and if the number to be printed has less digits then spaces shall be used for padding up to 'n' character)(e.g: 12 with %5d is <space><space><space>12). Right now I can extract the number between % and d but I don't know how to find the number of digits of the argument to be used, since we only specify that in main. If I knew the number of digits, I would write the following code inside case 'd':
Code:
for(i = 0; i < (precision - noDigits); i++)
{
putchar(' ');
}
I hope you understand what I'm trying to do, if not I'll try to explain more clearly. Thank you!!