Recreating Printf in C | Learning Programming

Have you ever wondered how C functions that are easy to use are made? Think about it. Could you recreate the printf function? Well no because the name is already taken, but we can create our own printf function a very basic form of it that is. We will need to use a function called a system call to accomplish this. A system call is a function that is built into the operating system that allows programmers to modify or use the operating system, so we can accomplish tasks. What we're going to have to do is use the read/write system calls. Normally when you call these functions in C you pass a file, however you can pass STDIN as a file and STDOUT as a file and you can read from STDIN, and write to STDOUT (which is the console) first let's make our basic printf


#include 
#include 
#include 
#include 

#define STDIN		0
#define STDOUT	1

void printf_mine(char *str, ...) {
	va_list valist;
	va_start(valist, str);

	for(int i = 0; i < strlen(str); i++) {
		if(str(i) == '%') {
			// TODO
		} else {
			char *a = &str[i];
			wrtie(STDOUT, a, 1); 
		}
	}
	va_end(valist);
}
int main() {
	printf_mine("Hello, world!\n");
	return 0;
}


Let's break down what we're seeing here:


#define STDIN		0
#define STOUT		1

We start by defining two constants STDIN and STDOUT, these are almost always 0 and 1 respectively. STDIN stands for standard input, while STDOUT stands for standard output. When outputting we use STDOUT, and when reading input we use STDIN


void printf_mine(char *str, ...) {
	va_list valist;
	va_start(valist, str);

	for(int i = 0; i < strlen(str); i++) {
		if(str(i) == '%') {
			// TODO
		} else {
			char *a = &str[i];
			wrtie(STDOUT, a, 1); 
		}
	}
	va_end(valist);
}

Let's look at this function definition. First we see that it's void, so it won't be returning anything. then we see it has two arguments char *str and '...' the '...' is to signify that we want to be able to have as many arguments as possible. We will use this later to make it function more closely to what prinf really does!


va_list valist;
va_start(valist, str);

These two lines are let us access that list of arguments from earlier. The first line is just making a va_list variable which stores all the information about the arguments that we might need. To load this variable with the data, we use the next line which takes two arguments our variable, and the first known variable of the function, so we pass str because that's the last argument we know of!


for(int i = 0; i < strlen(str); i++) {
		if(str(i) == '%') {
			// TODO
		} else {
			char *a = &str[i];
			wrtie(STDOUT, a, 1); 
		}
	}

Next is the for loop. This is going to let us go through each character in the string we passed. Now we have the guts of the for loop. The first if statement is checking for the special character '%' this is used in printf so that you can display variables, for now if that's the case we will just ignore that character (it won't get printed). If any other character is there though it will write each character one by one to the screen. The interesting line is this one


char *a = &str[i];

The write system call takes a char * value so to get that we take the memory address of the current character we are working with (str[i]) and assign it to a. Now we have our character in a char *, so we can give it to the function. Now all we have to do is call write. Write takes three arguments, the file descriptor, a char *, and the number of characters to write. We gave STDOUT as our file descriptor, the char a as our character, and 1 because it's a single character. To end off we do


va_end(valist); 

This just cleans up the memory of all those possible arguments from earlier. Now all that's left is the main function.


int main() {
	printf_mine("Hello, world!\n");
	return 0;
}

Here we are just calling our function with the words Hello, world! and a newline printed. Now this is just a really simple approach to recreating printf, and the escape character part isn't done. We will add on to this in another post!

Tags
C
Programming
Teaching
Linux
Learning
printf
Learn
Tutorial