Listing 1

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>

/*  repeat_format() - Function that generates from a string with
repeat count information, a new format string for printf().
*/

char *repeat_format(char *format)
    {
    char newfmt[256], tempstr[80], *fptr, *nptr, *tptr;
    int cnt, pcnt;
    
    for (nptr = newfmt, fptr = format; *fptr; fptr++)
       {
       if (*fptr == '%')
          {
          /*  if percent specifier found */
          tptr = tempstr;      /*  hold text in temporary string */
          cnt = 0;             /*  keep track of repeat count */
          *tptr++ = *fptr++;
          while (isdigit(*fptr))
              {
              /*  scan till non-digit found */
              *tptr++ = *fptr;
              cnt = cnt * 10 + (*fptr - '0');
              ++fptr;
              }
          *tptr = 0;           /* terminate temporary string */
          if ((*fptr == '(')  ||
              (*fptr == '%') ||
              (*fptr == ' '))
              {
              /*  data should be repeated*/
              if (*fptr == '(')
                 {
                 /*  if data is enclosed in parenthesis */
                 pcnt = 0;      /*  count parenthesis */
                 tptr = tempstr;
                 ++fptr;        /*  skip past opening paren */
                 for (;;)
                     {
                     if (*fptr == 0)
                         {
                         break;
                         }
                 else if (*fptr == ')')
                     {
                     if (pcnt == 0)
                         {
                         break;
                         }
                     else
                         {
                         --pcnt;
                         *tptr++ = *fptr++;
                         }
                     }
                 else if (*fptr == '(')
                     {
                     ++pcnt;
                     *tptr++ = *fptr++;
                     }
                 else
                     {
                     *tptr++ = *fptr++;
                     }
                 }
              *tptr = 0;     /*  use recursire call to format */
              strcpy(tempstr, repeat_format(tempstr));
              /*  string within parenthesis */
              }
          else
              {
              /*  else data not enclosed in parenthesis */
               tptr = tempstr;
               for (;;)
                  {
                  /*  scan till type specifier found */
                  *tptr++ = *fptr;
                  if (strchr(" duoxXfeEfGcs", *fptr))
                        break;
                   ++fptr;
                 }
              *tptr = 0;
              }
          for (; cnt; cnt--)
              {
              /*  now copy repeated info */
               for (tptr = tempstr; *tptr; tptr++)
                  {
                  *nptr++ = *tptr;
                  }
              }
         }
         else
              {
              /* wasn't repeated info, copy exactly, and scan on */
              for (tptr = tempstr; *tptr; tptr++)
                  {
                  *nptr++ = *tptr;
                  }
              *nptr++ = *fptr;
             }
       }
    else
       {
       *nptr++ = *fptr;
       }
    }
    *nptr = 0;
    return(newfmt);
   }
char *fmtstr[] =
   /*  some sample format strings to be converted */
   {
   " ABC %5%d",
   "%15 %3%d",
   "%5 (X=%d%6 AAA=%4(%c ) %d",
   "X%d %2 ( A%2d B%4%c ) %3d %2( %2( C%c D%2d))",
   "%2(%3(%3c %d ))",
   ""
   };

void main ()
   {
      int i;
      char newstr [250];
      
      for (i = 0;;i++)
          {
          if (fmtstr[i) [0] == 0)
                  break;
          strcpy(newstr, repeat_format(fmtstr[i] ));
          /* copy it for use locally */
          printf ("\r\n\"%s\" = \"%s\"", fmtstr[i), newstr);
          if (getch() == '\x1b')
                break;
          }
   }