/printf

C Custom Printf Function

Primary LanguageC

C - Custom printf function

Background Context

Custom printf function

printf

Requirements

General

  • Used editors: vi, vim
  • All files will compiled on Ubuntu 20.04 LTS using gcc, using the options -Wall -Werror -Wextra -pedantic -std=gnu89
  • All files end with a new line
  • Code for custom printf uses the Betty style. Checked using betty-style.pl and betty-doc.pl
  • No global variables used
  • No more than 5 functions per file
  • The prototypes of all your functions are included in header file called main.h
  • All header files are include guarded

More Info

Global functions and macros used

  • write (man 2 write)
  • malloc (man 3 malloc)
  • free (man 3 free)
  • va_start (man 3 va_start)
  • va_end (man 3 va_end)
  • va_copy (man 3 va_copy)
  • va_arg (man 3 va_arg)

Compilation

$ gcc -Wall -Werror -Wextra -pedantic -std=gnu89 *.c

Tasks

task0

Write a function that produces output according to a format.
  • Prototype: int _printf(const char *format, ...);
  • Returns: the number of characters printed (excluding the null byte used to end output to strings)
  • write output to stdout, the standard output stream
  • format is a character string. The format string is composed of zero or more directives. See man 3 printf for more detail. You need to handle the following conversion specifiers:
  • You don’t have to reproduce the buffer handling of the C library printf function
  • You don’t have to handle the flag characters
  • You don’t have to handle field width
  • You don’t have to handle precision
  • You don’t have to handle the length modifiers

task1

Handle the following conversion specifiers:
  • d

  • i

  • You don’t have to handle the flag characters

  • You don’t have to handle field width

  • You don’t have to handle precision

  • You don’t have to handle the length modifiers

task2

Handle the following custom conversion specifiers:
  • b: the unsigned int argument is converted to binary

task3

Handle the following conversion specifiers:

task4

Use a local buffer of 1024 chars in order to call write as little as possible.

task5

Handle the following custom conversion specifier:
  • S : prints the string. Print_String
  • Non printable characters (0 < ASCII value < 32 or >= 127) are printed this way: \x, followed by the ASCII code value in hexadecimal (upper case - always 2 characters)

task6

Handle the following conversion specifier: p.
  • You don’t have to handle the flag characters
  • You don’t have to handle field width
  • You don’t have to handle precision
  • You don’t have to handle the length modifiers

task7

Handle the following flag characters for non-custom conversion specifiers:

task8

Handle the following length modifiers for non-custom conversion specifiers:
  • l

  • h

  • Conversion specifiers to handle: d, i, u, o, x, X

task9

Handle the field width for non-custom conversion specifiers.

task10

Handle the precision for non-custom conversion specifiers.

task11

Handle the 0 flag character for non-custom conversion specifiers.

task12

Handle the - flag character for non-custom conversion specifiers.

task13

Handle the following custom conversion specifier:

task14

Handle the following custom conversion specifier:

task15

All the above options work well together.

Pseudocode

draw.io Pseudocode_For_Printf

Flow-Chart Diagram

_PRINTF

Implementation

  1. The function takes a format string and a variable number of arguments.

  2. It initialises variables including an integer i, printed, printed_chars, flags, width, precision, size, buff_ind, a char buffer with a size of BUFF_SIZE and a va_list named list

  3. The function checks if the format string is NULL and returns -1 if it is.

  4. It initialises the variable argument list and sets the buffer index to 0 and the printed characters to 0.

  5. The function iterates through the format string, for each iteration it checks if the current character is not '%'

  6. If the current character is not '%', it adds the character to the buffer and increments the buffer index by 1.

  7. If the buffer index reaches the size of the buffer, it calls the print_buffer function to print the buffer.

  8. If the current character is "%", it calls the helper functions get_flags, get_width, get_precision, get_size and handle_print to process the formatting

  9. It prints the output to the buffer and increments the printed_chars by the number of characters printed.

  10. At the end of the iteration; it calls the print_buffer function to print whatever is left in the buffer.

  11. The function ends the variable argument list and returns the total number of characters printed.

Collaborators

  • Yasmine Ben Ali
  • Samuel Selasi