Own printf Function in C

Own printf Function in C

Note: This implementation is simplified and may not cover all edge cases or advanced features of the standard printf function. Our printf function will print integers, characters and strings. Let's start with creating files. Our first file will be _putchar.c. We write this file like that:

#include <unistd.h>
#include "main.h"	
/**
 * _putchar - print character
 * @c: character
 * Return: only one character
*/

int _putchar(char c) {
	return (write(1, &c, 1));
}        

In this file we create a function that will print character. We use write function with help of unistd header file. write function can accept 3 arguments. First argument is 1. It means we will print. Second argument is c. It means we print c. Last argument is 1. It means we only print one character.

Then we create file named _puts.c. We write it like that:

#include "main.h"

/**
 * _puts - It will print string
 * @str: string
 * Return: length
*/
int _puts(char *str) {
	int length = 0;
	
	if (str == NULL) {
		str = "(null)";
	}
	
	if (str) {
		for (length = 0; str[length] != '\0'; length++) {
			_putchar(str[length]);
		}
	}
	
	return (length);
}        

In this file we create function that prints string. This function return length of string. If our string is NULL then string will be (null). Then we create a loop it helps us to print all character of string. '\0' means end of string.

Then we create _print_integer.c file. We write it like that:

#include "main.h"

/**
 * _print_number - convert integer to string
 * @length: length of number
 * @s: number to be converted
 * Return: void
*/

int _print_number(unsigned int length, int s) {
	int mod = 0, c = 0;
	unsigned int number;
	char buffer[11];
	
	/*For negative numbers*/
	if (s < 0) {
		_putchar('-');
		length++;
		number = -1 * s;
	} else {
		number = s;
	}
	
	if (number == 0) {
		_putchar(48);
		return (length + 1);
	}
	
	while (number > 0) {
		mod = number % 10;
		buffer[c] = mod + 48;
		number = number / 10;
		c++;
	}
	
	length = length + c;
	c = c - 1;
	
	while (c >= 0) {
		_putchar(buffer[c]);
		c--;
	}
	
	return (length);
}        

In here s is integer to be printed. mod: Used to store the remainder when dividing the number by 10. c: Used as an index for the buffer array.

number: Used to store the absolute value of the input integer. buffer: An array of characters used to store the digits of the number as characters.

If s is negative, it prints a minus sign (-) and updates the length accordingly. It then takes the absolute value of s to work with its magnitude.

If the input number is zero, it directly prints the character '0' and returns the updated length.

It iterates through each digit of the number using a while loop and stores each digit as a character in the buffer array. It does this by getting the remainder when dividing by 10 and then dividing the number by 10 to move to the next digit. It increments c to move to the next position in the buffer array. It adds the count of digits stored in c to the length. It prints the characters in reverse order. It iterates through the buffer array in reverse order and prints each character using the _putchar function.

Then we create _printf.c file. We write it like that:

#include <stdarg.h>
#include "main.h"

/**
 * _printf - own printf function it will work like printf function
 * @format: type specifier. ex: _printf("%d") will print decimal
 				_printf("%c") will print character
 				_printf("%s") will print string
 * Return: number of character printed
*/
int _printf(const char* format, ...) {
	va_list argumentList;
	int length = 0;
	int i;
	
	va_start(argumentList, format);
	
	for (i = 0; format[i] != '\0'; i++) {
		//We check cases here
		
		/*If there is no '%' sign print string or character*/
		if (format[i] != '%') {
			_putchar(format[i]);
		}
		
		/*If there is only one % print nothing*/
		else if (format[i] == '%' && format[i + 1] == '\0') {
			_putchar(' ');
		}
		
		/*If there double % it will print one %*/
		else if (format[i] == '%' && format[i + 1] == '%') {
			_putchar('%');
		}
		
		/*If there is c after % print character*/
		else if (format[i] == '%' && format[i + 1] == 'c') {
			_putchar(va_arg(argumentList, int));
			i++;
		}
		
		/*If there is s after % print string*/
		else if (format[i] == '%' && format[i + 1] == 's') {
			_puts(va_arg(argumentList, char *));
			i++;
		}
		else if (format[i] == '%' && (format[i + 1] == 'd' || format[i + 1] == 'i')) {
			length = _print_number(length, va_arg(argumentList, int));
			i++;
		}
	}
	
	va_end(argumentList);
	return (length);
}        

We create _printf function as a variadic function. Because we don't know number of arguments. A variadic function is a function in C programming language that can take a variable number of arguments. These functions are particularly useful in situations where the number of arguments needed is not known beforehand.

In this file we use stdarg.h header file. This header file help us to use va_list, va_start, va_arg and va_end macros.

  • The va_list macro is used to declare a variable that will hold the list of arguments passed to the function.
  • va_start macro is used to initialize a va_list object for accessing the variable arguments in a variadic function.
  • va_arg is a macro is used to retrieve the next argument from a variable argument list of a variadic function.
  • va_end is a macro is used to perform cleanup operations on a va_list object after it has been used to access variable arguments in a variadic function.

We create loop in here. It checks format. If there is no '%' sign it will print only string which writed in _printf(). If there is one '%' it will print nothing.

If there is double '%' it will print only one '%'. If there is '%c' _putchar(vaarg(argumentList, int)) essentially outputs the next character from the variable argument list argumentList to the standard output.

If there is '%s' _puts(vaarg(argumentList, char *)) essentially outputs the next C string from the variable argument list argumentList to the standard output.

If there is '%d' or '%i' length = _print_number(length, va_arg(argumentList, int)) essentially processes the next integer argument from the variable argument list argumentList using the _print_number function, and updates the length variable with the return value of _print_number.

Then we create main.h. We write it like that:

#ifndef MAIN_H
#define MAIN_H

#include "_putchar.c"
#include "_printf.c"
#include "_puts.c"
#include "_print_integer.c"

/*Function prototypes*/
int _printf(const char* format, ...);
int _putchar(char c);
int _puts(char *str);
int _print_number(unsigned int length, int s);

#endif        

It will hold function protypes and we include our files which we write functions on it. #ifndef, #define, #endif macros prevent the main.h file from being endlessly appended to our program.

Finally we create main.c file to check our cases. We write it like that:#include "main.h"

#include "main.h"

int main(void) {
	
	int number1 = 12.6;
	int number2 = 23;
	char character = 'A';
	char string[100] = "Own printf function in C";

	/*printing only string without '%' sign*/
	_printf("Hello, World!\n");

	/*printing only one character*/
	_printf("A\n");

	/*printing with one '%' sign. It will print nothing.*/
	_printf("%\n");

	/*printing with double '%' sign. It will print only one %*/
	_printf("%%\n");

	/*printing character with %c*/
	_printf("Character: %c\n", character);
	
	/*printing string with %s*/
	_printf("String: %s\n", string);
	
	/*printing decimal with %d and %i*/
	_printf("Decimal: %d\n", number1);
	_printf("Decimal: %i\n", number2);
	
	return (0);
}        

We include our main.h file and we test cases.

GitHub Link: https://github.com/nihad1213/Own-printf-Function-in-C

To view or add a comment, sign in

More articles by Nihad Namatli

  • PHP ilə terminalda necə rəngli yazılar yazmaq olar?

    Rubydə sadə terminal proqramı yazarkən error mesajının qırmızı yazılmasını istəmişdim. Və bunun üçün rainbow adlı…

    1 Comment
  • PHP-də necə REST API yazmaq olar?

    İstifadə etdiyim Tool-lar və Proqramlar: XAMPP: XAMPP server mühitidir. XAMPP açıq mənbəli bir layihədir və Windows…

    1 Comment

Others also viewed

Explore content categories