Thread: How to count number of digits of printf argument?

  1. #1
    Registered User
    Join Date
    Oct 2020
    Posts
    69

    How to count number of digits of printf argument?

    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!!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,617
    Code:
            if(isdigit(*format))
            {
                precision = atoi(format);
                format++;
                continue;
            }
    I think this should be
    Code:
    if(isdigit(*format)) {
        precision = strtol(format,&format,10);
    }
    This will store (in your case, 4) in the precision, and advance format to point to the 'd' of the conversion specifier.

    > 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)
    Well rather than doing this
    > fputs(convert(num,10), stdout);

    Maybe something like
    Code:
    char *out = convert(num,10);
    noDigits = strlen(out);
    // your padding code
    fputs(out,stdout);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to count odd digits in unsigned long number in C
    By bdaniel2 in forum C Programming
    Replies: 4
    Last Post: 02-10-2018, 09:10 PM
  2. Replies: 7
    Last Post: 02-20-2013, 12:28 AM
  3. Count the number of vowels, consonants, digits etc.
    By kumar14878 in forum C Programming
    Replies: 3
    Last Post: 05-09-2005, 12:34 AM
  4. count digits
    By Mariana in forum C++ Programming
    Replies: 7
    Last Post: 03-03-2004, 07:56 PM
  5. Count Number of Digits in and Integer
    By redneon in forum C++ Programming
    Replies: 2
    Last Post: 08-18-2003, 04:16 PM

Tags for this Thread