I'm making a hobbyist kernel and I'm trying to implement a printf() function.
Here's my implementation:
void kprint(uint8_t *format, ...) {
  va_list ap;
  va_start(ap, format);
  uint8_t *ptr;
  for (ptr = format; *ptr != '\0'; ptr++) {
    if (*ptr == '%') {
      ptr++;
      switch (*ptr) {
        case 's':
          puts(va_arg(ap, uint8_t *), 0x0F, xPos, yPos);
          break;
      }
    } else {
      puts(ptr, 0x0F, xPos, yPos);
      ptr++;
    }
  }
  va_end(ap);
}
When I want to print "Hello World!" using this function it returns me that:
"Hello %sllo %so %sWorld"
Here's function call:
kprint("Hello %s", "World");
                the main issue is that you're using puts to print the rest of the string instead of current char.
 } else {
   puts(ptr, 0x0F, xPos, yPos);
   ptr++;
}
also you're incrementing ptr when it's already done in the loop. Useful to consume format argument, but not in that case.
A working implementation (not using the strange puts prototype) that works on a standard system (tested on windows gcc):
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
void zprintf(uint8_t *format, ...)
  {
      va_list ap;
      va_start(ap, format);
      uint8_t *ptr;
      for (ptr = format; *ptr != '\0'; ptr++) {
          if (*ptr == '%') {
              ptr++;
              switch (*ptr) {
                  case 's':
                      fputs(va_arg(ap, uint8_t *),stdout);
                      break;
                 case '%':
                      putchar('%');
                      break;
              }
             } else {
               putchar(*ptr);
            }
           }
           va_end(ap);
}
int main(){
    zprintf("%% Hello %s\n","World");    
    return 0;
}
prints:
% Hello World
(as a bonus, this implementation handles the escaped % char)
Using only your special implementation of puts you could change
 } else {
   puts(ptr, 0x0F, xPos, yPos);
   ptr++;
}
to a working:
 } else {
   char c[2];
   c[0] = *ptr; c[1] = '\0';
   puts(c, 0x0F, xPos, yPos);
 }
lame but would work :)
void kprint(char *format, ...) 
{
    va_list ap;
    va_start(ap, format);
    char *ptr = format;
  while(*ptr)
  {
    if (*ptr == '%') 
    {
      ptr++;
      switch (*ptr++) 
      {
        case 's':
          printf("%s", va_arg(ap, char *));
          break;
      }
    } 
    else 
    {
      putchar(*ptr++);
    }
  }
  va_end(ap);
}
int main()
{
    kprint("Hello %s World%s", "AAAAA", " BBBBBB");
    return 0;
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With