Thread: minprintf

  1. #1
    Registered User
    Join Date
    Jul 2009
    Location
    Croatia
    Posts
    272

    minprintf

    Im working on my own printf function currently.

    And im looking for ideas what would be an practical way of doing if the functions finds a NULL character while searching for an argument;

    for example, what should printf do if it finds a string like this... printf("%10");

    I bolded the key parts.

    Also, is there a finer way to deal with those situations?

    The way i handled it is i just return from the function.

    Edit: i also noticed the standard printf function also doesnt print anything in printf("%10"); case.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include <ctype.h>
    #include <string.h>
    
    void align(int n);
    
    void minprintf(char *fmt, ...)
    {
         va_list ap;
         char *p;
         
         enum alignments { LEFT, RIGHT }; /* alignment */
         int alignment;
         int width;
         int precision;
         void align_left(int precision, int width, char *stringp);
         void align_right(int precision, int width, char *stringp);
         
         int count;
         char *nump;
         
         int ival;
         double dval;
         char *sval;
         
         va_start(ap, fmt);
         for(p = fmt; *p; p++) {
               if(*p != '%') {
                     putchar(*p);
                     continue;
               }
               if(*++p == '\0')
                   return;
               if(*p == '-') {
                     alignment = LEFT;
                     if(*++p == '\0')
                        return;
               } else 
                     alignment = RIGHT;
               width = precision = 0;
               if(isdigit(*p) && *p) 
                    while(isdigit(*p)) {
                       width = width * 10 + *p - '0';
                       p++;
                    }
               if(*p == '\0')
                  return;
               if(*p == '.') 
                    while(isdigit(*++p) && *p) 
                       precision = precision * 10 + *p - '0';
               if(*p == '\0')
                  return;
                  
               char string[50];
               switch(*p) {
                   case 'd':
                   case 'i':
                        ival = va_arg(ap, int);
                        itoa(ival, string, 10);
                        if(alignment == LEFT) 
                            align_left(precision, width, string);
                        else 
                            align_right(precision, width, string);
                        break;
                   case 's':
                        sval = va_arg(ap, char *);
                        if(alignment == LEFT) 
                            align_left(precision, width, sval);
                        else 
                            align_right(precision, width, sval);
                        break;
                   default:
                           putchar(*p);
                           break;
               }
         }
         va_end(ap);
    }
              
    void align(int n)
    {
         int i;
         
         for(i = 0; i < n; i++)
              putchar(' ');
    }
               
    void align_left(int precision, int width, char *stringp)
    {
           int count;
           
           count = 0;
           if(precision) {
                 while(precision-- && *stringp) {
                    putchar(*stringp);
                    stringp++;
                    count++;
                 }
           } else {
                   printf("%s", stringp);
                   count += strlen(stringp);
           }
           if(count < width) 
                align(width - count);
    }
    
    void align_right(int precision, int width, char *stringp)
    {
           int count;
           
           count = 0;
           if(precision) {
                align(width - precision);
                while(precision-- && *stringp) {
                     putchar(*stringp);
                     stringp++;
                }
           } else {
                  count += strlen(stringp);
                  align(width - count);
                  printf("%s", stringp);
           }
    }
                      
    
    int main()
    {
          minprintf("%-15.10s", "hello, word");
          getchar();
          return 0;
    }
    Last edited by Tool; 02-14-2010 at 04:27 PM.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Give your printf function a return value and return true or false depending on success. It's the standard way of doing it.
    If you notice a malformed input string, make sure to fail.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Jul 2009
    Location
    Croatia
    Posts
    272
    And checking 3 times for NULL sign is a must, right? Cannot be shortened in thise case? Looks a bit "ugly".
    Last edited by Tool; 02-14-2010 at 04:32 PM.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Better safe than sorry. The pointer p can be incremented between those checks.
    So I would say it's necessary.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Jul 2009
    Location
    Croatia
    Posts
    272
    Fascinating you're still here.

    I remember you about like 4 months ago when you explained me some things about EOF.

    Now im really close to finish reading K&R, and partly because of your help!

    So, thanks!

Popular pages Recent additions subscribe to a feed