You need to understand the “va_arg” stuff - how to unpack the extra parameters after the format string when you don’t know how many of them there will be.
Unfortunately, “va_arg” is OS and CPU dependent - it might be a library, it might be inline assembly language or it might even be built into your C compiler. If you’re not allowed to use any libraries whatever - then you might have to write assembly code to do that…but most people consider va_arg to be “a part of the C language” - so probably you can use it OK.
After you cross that hurdle, printf and scanf are both fairly straight forward pieces of code to write.
I haven’t written my own ‘scanf’ for a very long time…but I wrote my own printf quite recently…’scanf’ would demand similar tactics - so I’m just going to talk about printf.
I decided to first write ‘vsnprintf’ (Google that!) which uses a string for output - this is where the guts of printf (and it’s close cousins) lives. Then you can write printf, fprintf and sprintf in a couple of lines of code each because they are just calls to ‘vsnprintf’ - followed by whatever code you need to send the data to the output.
The business of outputting a string to the screen (or a file) normally requires you to use the standard IO library to actually do that (using ‘fputs’ or maybe ‘putchar’/’fputc’ in a loop - for example).
If you REALLY can’t use a library of any kind - then you have to make a call to whatever operating system you have. Under Linux, you can make a call to the “write” system function - but without using a library, you have to know how to use the super-low-level ‘syscall’ function to do that. syscall is machine code.
I have no idea how you’d do it under Windows without using any kind of library…but it should be possible in principle. To be honest - it’s a dumb thing to try…just use ‘write’ for chrissakes!
On an embedded system (the last time I had to write my own ‘printf’ - it was for that kind of a machine) - you don’t typically have an operating system at all.,,and you may not even have “putchar”. (I didn’t!)
So you’d first want to write your own “putchar” function - and to do that, you might have to write code to talk to the serial port hardware, probably using interrupts and such…which is more or less what I did. That’s actually more code than “printf”…and it’s horrible to get right. Fortunately, most embedded processors come with example programs that you can copy here.
I didn’t write the COMPLETE implementation of printf (it’s a lot of work) - mine only works for %d, %u, %i, %x, %c and %s - and has limited support for field widths, leading zeroes and such…but that was all I needed - and I can easily add more in the future if necessary.
My code for vsnprintf, snprintf, printf, fprintf and sprintf comes out to 124 lines of code (including lots of white-space and comments)…so it’s not a horribly difficult project.
If I DO have to write scanf - I’ll take the same approach, write “vssscanf” first - and use that to write scanf, fscanf and sscanf - writing my on “fgets” function that’ll call “fgetc” - which will do low level I/O with interrupts.
One of the nice things about doing all of this is that my embedded computer supports WiFi connections - and I was able to write “wprintf” that sends it’s results to the WiFi controller.