https://github.com/samuelselasi/printf
C Custom Printf Function
https://github.com/samuelselasi/printf
alx-low-level-programming alx-system-engineering c pointers-and-arrays printf struct typedef variadic-functions
Last synced: 9 months ago
JSON representation
C Custom Printf Function
- Host: GitHub
- URL: https://github.com/samuelselasi/printf
- Owner: samuelselasi
- Created: 2023-01-20T22:57:16.000Z (almost 3 years ago)
- Default Branch: master
- Last Pushed: 2023-02-27T16:53:47.000Z (almost 3 years ago)
- Last Synced: 2025-01-23T13:43:55.794Z (11 months ago)
- Topics: alx-low-level-programming, alx-system-engineering, c, pointers-and-arrays, printf, struct, typedef, variadic-functions
- Language: C
- Homepage: https://github.com/samuelselasi/printf
- Size: 111 KB
- Stars: 0
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# C - Custom printf function
## Background Context
```
Custom printf function
```

## 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](https://github.com/holbertonschool/Betty/blob/master/betty-style.pl) and [betty-doc.pl](https://github.com/holbertonschool/Betty/blob/master/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](./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](./printf.c)
```
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:
* [c](./print_char.c)
* [s](./print_string.c)
* [%](./_printf.c)
* 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](./_printf.c)
```
Handle the following conversion specifiers:
```
* [d](./print_int.c)
* [i](./print_int.c)
* 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](./_printf.c)
```
Handle the following custom conversion specifiers:
```
* b: the unsigned int argument is converted to binary
* [Print_Binary](./print_binary.c)
[task3](./printf.c)
```
Handle the following conversion specifiers:
```
* u:
* [Print_Unsigned](./print_unsigned.c)
* o:
* [Print_Octal](./print_octal.c)
* x:
* [Print_Hexadecimal](./print_hexadecimal.c)
* [Print_Lower_Hex_Chars](./print_hex_lower.c)
* X:
* [Print_Hexadecimal](./print_hexadecimal.c)
* [Print_Upper_Hex_Chars](./print_hex_upper.c)
* 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
[task4](./_printf.c)
```
Use a local buffer of 1024 chars in order to call write as little as possible.
```
* [buffer](./print_buffer.c)
[task5](./_printf.c)
```
Handle the following custom conversion specifier:
```
* S : prints the string. [Print_String](./print_string.c)
* 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)
* [Print_Non-Printable_Chars](./print_non_printable.c)
[task6](./_printf.c)
```
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
* [Print_Pointer](./print_pointer.c)
[task7](./_printf.c)
```
Handle the following flag characters for non-custom conversion specifiers:
```
* [+](./get_flags.c)
* [space](./get_flags.c)
* [#](./get_flags.c)
[task8](./_printf.c)
```
Handle the following length modifiers for non-custom conversion specifiers:
```
* [l](./convert_size_number.c)
* [h](./convert_size_unsigned.c)
* Conversion specifiers to handle: d, i, u, o, x, X
[task9](./_printf.c)
```
Handle the field width for non-custom conversion specifiers.
```
* [Handle_Field_Width](./get_width.c)
[task10](./_printf.c)
```
Handle the precision for non-custom conversion specifiers.
```
* [Handle_Precision](./get_precision.c)
[task11](./_printf.c)
```
Handle the 0 flag character for non-custom conversion specifiers.
```
* [Handle_0_Flag](./nprint_int.c)
[task12](./_printf.c)
```
Handle the - flag character for non-custom conversion specifiers.
```
* [Handle_-_Flag](./get_flags.c)
[task13](./_printf.c)
```
Handle the following custom conversion specifier:
```
* r : prints the reversed string.
* [Handle_String_Reverse](./print_reverse.c)
[task14](./_printf.c)
```
Handle the following custom conversion specifier:
```
* R: prints the rot13'ed string
* [Rot13_Encryption](./print_rot13.c)
[task15](./_printf.c)
```
All the above options work well together.
```
* [header_file](./main.h)
## Pseudocode
[draw.io](https://drive.google.com/file/d/1PCFpX56mtAerF7RS7wzx9HCEFXc-Drib/view?usp=sharing)
[Pseudocode_For_Printf](./https://docs.google.com/document/d/1BOKUnRWP_8GRWBPqD_BZW-OB2V7Nh4YgCH765JsM1gg/edit?usp=sharing)
## Flow-Chart Diagram

## 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**