├── print_size.c ├── print_width.c ├── print_f.c ├── print_precision.c ├── _printf.c ├── print_handle.c ├── printable.c ├── man_printf ├── main.h ├── print_h_u.c ├── print_p_r_rot13.c ├── print_c_s.c ├── print_write.c └── README.md /print_size.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | /** 4 | * get_size - Calculates the size to cast the argument 5 | * @format: Formatted string in which to print the arguments 6 | * @i: List of arguments to be printed. 7 | * 8 | * Return: Precision. 9 | */ 10 | int get_size(const char *format, int *i) 11 | { 12 | int curr_i = *i + 1; 13 | int size = 0; 14 | 15 | if (format[curr_i] == 'l') 16 | size = S_LONG; 17 | else if (format[curr_i] == 'h') 18 | size = S_SHORT; 19 | 20 | if (size == 0) 21 | *i = curr_i - 1; 22 | else 23 | *i = curr_i; 24 | 25 | return (size); 26 | } 27 | -------------------------------------------------------------------------------- /print_width.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | /** 4 | * get_width - Calculates the width for printing 5 | * @format: Formatted string in which to print the arguments. 6 | * @i: List of arguments to be printed. 7 | * @list: list of arguments. 8 | * 9 | * Return: width. 10 | */ 11 | int get_width(const char *format, int *i, va_list list) 12 | { 13 | int curr_i; 14 | int width = 0; 15 | 16 | for (curr_i = *i + 1; format[curr_i] != '\0'; curr_i++) 17 | { 18 | if (is_digit(format[curr_i])) 19 | { 20 | width *= 10; 21 | width += format[curr_i] - '0'; 22 | } 23 | else if (format[curr_i] == '*') 24 | { 25 | curr_i++; 26 | width = va_arg(list, int); 27 | break; 28 | } 29 | else 30 | break; 31 | } 32 | 33 | *i = curr_i - 1; 34 | 35 | return (width); 36 | } 37 | -------------------------------------------------------------------------------- /print_f.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | /** 4 | * get_flags - Calculates active flags 5 | * @format: Formatted string in which to print the arguments 6 | * @i: take a parameter. 7 | * Return: Flags: 8 | */ 9 | int get_flags(const char *format, int *i) 10 | { 11 | /* - + 0 # ' ' */ 12 | /* 1 2 4 8 16 */ 13 | int j, curr_i; 14 | int flags = 0; 15 | const char FLAGS_CH[] = {'-', '+', '0', '#', ' ', '\0'}; 16 | const int FLAGS_ARR[] = {F_MINUS, F_PLUS, F_ZERO, F_HASH, F_SPACE, 0}; 17 | 18 | for (curr_i = *i + 1; format[curr_i] != '\0'; curr_i++) 19 | { 20 | for (j = 0; FLAGS_CH[j] != '\0'; j++) 21 | if (format[curr_i] == FLAGS_CH[j]) 22 | { 23 | flags |= FLAGS_ARR[j]; 24 | break; 25 | } 26 | 27 | if (FLAGS_CH[j] == 0) 28 | break; 29 | } 30 | 31 | *i = curr_i - 1; 32 | 33 | return (flags); 34 | } 35 | -------------------------------------------------------------------------------- /print_precision.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | /** 4 | * get_precision - Calculates the precision for printing 5 | * @format: Formatted string in which to print the arguments 6 | * @i: List of arguments to be printed. 7 | * @list: list of arguments. 8 | * 9 | * Return: Precision. 10 | */ 11 | int get_precision(const char *format, int *i, va_list list) 12 | { 13 | int curr_i = *i + 1; 14 | int precision = -1; 15 | 16 | if (format[curr_i] != '.') 17 | return (precision); 18 | 19 | precision = 0; 20 | 21 | for (curr_i += 1; format[curr_i] != '\0'; curr_i++) 22 | { 23 | if (is_digit(format[curr_i])) 24 | { 25 | precision *= 10; 26 | precision += format[curr_i] - '0'; 27 | } 28 | else if (format[curr_i] == '*') 29 | { 30 | curr_i++; 31 | precision = va_arg(list, int); 32 | break; 33 | } 34 | else 35 | break; 36 | } 37 | 38 | *i = curr_i - 1; 39 | 40 | return (precision); 41 | } 42 | -------------------------------------------------------------------------------- /_printf.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | void print_buffer(char buffer[], int *buff_ind); 4 | 5 | /** 6 | * _printf - Printf function 7 | * @format: format. 8 | * Return: Printed chars. 9 | */ 10 | int _printf(const char *format, ...) 11 | { 12 | int i, printed = 0, printed_chars = 0; 13 | int flags, width, precision, size, buff_ind = 0; 14 | va_list list; 15 | char buffer[BUFF_SIZE]; 16 | 17 | if (format == NULL) 18 | return (-1); 19 | 20 | va_start(list, format); 21 | 22 | for (i = 0; format && format[i] != '\0'; i++) 23 | { 24 | if (format[i] != '%') 25 | { 26 | buffer[buff_ind++] = format[i]; 27 | if (buff_ind == BUFF_SIZE) 28 | print_buffer(buffer, &buff_ind); 29 | /* write(1, &format[i], 1);*/ 30 | printed_chars++; 31 | } 32 | else 33 | { 34 | print_buffer(buffer, &buff_ind); 35 | flags = get_flags(format, &i); 36 | width = get_width(format, &i, list); 37 | precision = get_precision(format, &i, list); 38 | size = get_size(format, &i); 39 | ++i; 40 | printed = handle_print(format, &i, list, buffer, 41 | flags, width, precision, size); 42 | if (printed == -1) 43 | return (-1); 44 | printed_chars += printed; 45 | } 46 | } 47 | 48 | print_buffer(buffer, &buff_ind); 49 | 50 | va_end(list); 51 | 52 | return (printed_chars); 53 | } 54 | 55 | /** 56 | * print_buffer - Prints the contents of the buffer if it exist 57 | * @buffer: Array of chars 58 | * @buff_ind: Index at which to add next char, represents the length. 59 | */ 60 | void print_buffer(char buffer[], int *buff_ind) 61 | { 62 | if (*buff_ind > 0) 63 | write(1, &buffer[0], *buff_ind); 64 | 65 | *buff_ind = 0; 66 | } 67 | -------------------------------------------------------------------------------- /print_handle.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | /** 3 | * handle_print - Prints an argument based on its type 4 | * @fmt: Formatted string in which to print the arguments. 5 | * @list: List of arguments to be printed. 6 | * @ind: ind. 7 | * @buffer: Buffer array to handle print. 8 | * @flags: Calculates active flags 9 | * @width: get width. 10 | * @precision: Precision specification 11 | * @size: Size specifier 12 | * Return: 1 or 2; 13 | */ 14 | int handle_print(const char *fmt, int *ind, va_list list, char buffer[], 15 | int flags, int width, int precision, int size) 16 | { 17 | int i, unknow_len = 0, printed_chars = -1; 18 | fmt_t fmt_types[] = { 19 | {'c', print_char}, {'s', print_string}, {'%', print_percent}, 20 | {'i', print_int}, {'d', print_int}, {'b', print_binary}, 21 | {'u', print_unsigned}, {'o', print_octal}, {'x', print_hexadecimal}, 22 | {'X', print_hexa_upper}, {'p', print_pointer}, {'S', print_non_printable}, 23 | {'r', print_reverse}, {'R', print_rot13string}, {'\0', NULL} 24 | }; 25 | for (i = 0; fmt_types[i].fmt != '\0'; i++) 26 | if (fmt[*ind] == fmt_types[i].fmt) 27 | return (fmt_types[i].fn(list, buffer, flags, width, precision, size)); 28 | 29 | if (fmt_types[i].fmt == '\0') 30 | { 31 | if (fmt[*ind] == '\0') 32 | return (-1); 33 | unknow_len += write(1, "%%", 1); 34 | if (fmt[*ind - 1] == ' ') 35 | unknow_len += write(1, " ", 1); 36 | else if (width) 37 | { 38 | --(*ind); 39 | while (fmt[*ind] != ' ' && fmt[*ind] != '%') 40 | --(*ind); 41 | if (fmt[*ind] == ' ') 42 | --(*ind); 43 | return (1); 44 | } 45 | unknow_len += write(1, &fmt[*ind], 1); 46 | return (unknow_len); 47 | } 48 | return (printed_chars); 49 | } 50 | -------------------------------------------------------------------------------- /printable.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | /** 4 | * is_printable - Evaluates if a char is printable 5 | * @c: Char to be evaluated. 6 | * 7 | * Return: 1 if c is printable, 0 otherwise 8 | */ 9 | int is_printable(char c) 10 | { 11 | if (c >= 32 && c < 127) 12 | return (1); 13 | 14 | return (0); 15 | } 16 | 17 | /** 18 | * append_hexa_code - Append ascci in hexadecimal code to buffer 19 | * @buffer: Array of chars. 20 | * @i: Index at which to start appending. 21 | * @ascii_code: ASSCI CODE. 22 | * Return: Always 3 23 | */ 24 | int append_hexa_code(char ascii_code, char buffer[], int i) 25 | { 26 | char map_to[] = "0123456789ABCDEF"; 27 | /* The hexa format code is always 2 digits long */ 28 | if (ascii_code < 0) 29 | ascii_code *= -1; 30 | 31 | buffer[i++] = '\\'; 32 | buffer[i++] = 'x'; 33 | 34 | buffer[i++] = map_to[ascii_code / 16]; 35 | buffer[i] = map_to[ascii_code % 16]; 36 | 37 | return (3); 38 | } 39 | 40 | /** 41 | * is_digit - Verifies if a char is a digit 42 | * @c: Char to be evaluated 43 | * 44 | * Return: 1 if c is a digit, 0 otherwise 45 | */ 46 | int is_digit(char c) 47 | { 48 | if (c >= '0' && c <= '9') 49 | return (1); 50 | 51 | return (0); 52 | } 53 | 54 | /** 55 | * convert_size_number - Casts a number to the specified size 56 | * @num: Number to be casted. 57 | * @size: Number indicating the type to be casted. 58 | * 59 | * Return: Casted value of num 60 | */ 61 | long int convert_size_number(long int num, int size) 62 | { 63 | if (size == S_LONG) 64 | return (num); 65 | else if (size == S_SHORT) 66 | return ((short)num); 67 | 68 | return ((int)num); 69 | } 70 | 71 | /** 72 | * convert_size_unsgnd - Casts a number to the specified size 73 | * @num: Number to be casted 74 | * @size: Number indicating the type to be casted 75 | * 76 | * Return: Casted value of num 77 | */ 78 | long int convert_size_unsgnd(unsigned long int num, int size) 79 | { 80 | if (size == S_LONG) 81 | return (num); 82 | else if (size == S_SHORT) 83 | return ((unsigned short)num); 84 | 85 | return ((unsigned int)num); 86 | } 87 | -------------------------------------------------------------------------------- /man_printf: -------------------------------------------------------------------------------- 1 | .TH _printf 3 "22 Jan 2023" "" "_printf man page" 2 | .SH NAME 3 | _printf \- a basic replica of the standard printf function 4 | 5 | .SH SYNOPSIS 6 | .B #include \(dqmain.h\(dq 7 | 8 | .BI "int _printf(const char *" "format, ..." ");" 9 | 10 | .SH DESCRIPTION 11 | Write output to stdout using the format string. The format string is comprised of 0 or more directives and contains specifiers beginning with the character \(dq%\(dq. The specifier use the corresponding argument to print the variable. 12 | 13 | .SH RETURN VALUE 14 | On success, \fB_printf\fR returns the number of bytes printed, excluding the null byte. On failure, returns -1. 15 | 16 | .SH SPECIFERS 17 | .TP 18 | d, i 19 | The int argument is printed in signed decimal notation 20 | .TP 21 | u 22 | The \fIunsigned int\fR argument is printed in unsigned decimal notation 23 | .TP 24 | o 25 | The \fIunsigned int\fR argument is printed in unsigned octal notation 26 | .TP 27 | x, X 28 | The \fIunsigned int\fR argument is printed in unsigned hexadecimal notation. The letters \(dqabcdef\(dq are used for x; the letters \(dqABCDEF\(dq are used for X. 29 | .TP 30 | b 31 | The \fIunsigned int\fR argument is printed in unsigned binary notation. 32 | .TP 33 | c 34 | The \fIint\fR argument is converted to an \fIunsigned char\fR and printed. 35 | .TP 36 | s 37 | The \fIconst char *\fR argument is expected to be a pointer to a character array. Characters up to, but not including, the terminating null byte are written 38 | .TP 39 | % 40 | A '%' is written. No argument is converted. 41 | .TP 42 | p 43 | The \fIvoid *\fR pointer argument is printed in hexadecimal format beginning with '0x'. 44 | .TP 45 | r 46 | The \fIconst char *\fR argument is expected to be a pointer to a character array. Characters are written in reverse order up to, but not including, the terminating null byte. 47 | .TP 48 | R 49 | The \fIconst char *\fR argument is expected to be a pointer to a character array. Characters are encoded into ROT13 and written up to, but not including, the terminating null byte. 50 | .TP 51 | F 52 | Regardless of what is passed to the function, this specifier only prints an expletive. 53 | 54 | 55 | .SH EXAMPLE 56 | To print text mixed with a \fIname\fR string variable and an \fIage\fR integer variable: 57 | .PP 58 | .nf 59 | .RS 60 | #include "main.h" 61 | #include 62 | 63 | int main(int ac, char **av) 64 | { 65 | int age; 66 | char *name; 67 | 68 | if (ac != 3) 69 | return (-1); 70 | 71 | name = av[1]; 72 | age = atoi(av[2]); 73 | 74 | _printf("Hello! My name is %s and I am %d years old.\n", name, age); 75 | 76 | return (0); 77 | } 78 | .fi 79 | .PP 80 | 81 | .SH SEE ALSO 82 | .BR printf (3) 83 | 84 | .SH AUTHOR 85 | Solomon kassa, Nawwal Ismael 86 | .https://github.com/Solomonkassa/printf/edit/master/man_printf 87 | 88 | 89 | -------------------------------------------------------------------------------- /main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | #include 4 | #include 5 | #include 6 | 7 | #define UNUSED(x) (void)(x) 8 | #define BUFF_SIZE 1024 9 | 10 | /* FLAGS */ 11 | #define F_MINUS 1 12 | #define F_PLUS 2 13 | #define F_ZERO 4 14 | #define F_HASH 8 15 | #define F_SPACE 16 16 | 17 | /* SIZES */ 18 | #define S_LONG 2 19 | #define S_SHORT 1 20 | 21 | /** 22 | * struct fmt - Struct op 23 | * 24 | * @fmt: The format. 25 | * @fn: The function associated. 26 | */ 27 | struct fmt 28 | { 29 | char fmt; 30 | int (*fn)(va_list, char[], int, int, int, int); 31 | }; 32 | 33 | 34 | /** 35 | * typedef struct fmt fmt_t - Struct op 36 | * 37 | * @fmt: The format. 38 | * @fm_t: The function associated. 39 | */ 40 | typedef struct fmt fmt_t; 41 | 42 | int _printf(const char *format, ...); 43 | int handle_print(const char *fmt, int *i, 44 | va_list list, char buffer[], int flags, int width, int precision, int size); 45 | 46 | /****************** FUNCTIONS ******************/ 47 | 48 | /* Funtions to print chars and strings */ 49 | int print_char(va_list types, char buffer[], 50 | int flags, int width, int precision, int size); 51 | int print_string(va_list types, char buffer[], 52 | int flags, int width, int precision, int size); 53 | int print_percent(va_list types, char buffer[], 54 | int flags, int width, int precision, int size); 55 | 56 | /* Functions to print numbers */ 57 | int print_int(va_list types, char buffer[], 58 | int flags, int width, int precision, int size); 59 | int print_binary(va_list types, char buffer[], 60 | int flags, int width, int precision, int size); 61 | int print_unsigned(va_list types, char buffer[], 62 | int flags, int width, int precision, int size); 63 | int print_octal(va_list types, char buffer[], 64 | int flags, int width, int precision, int size); 65 | int print_hexadecimal(va_list types, char buffer[], 66 | int flags, int width, int precision, int size); 67 | int print_hexa_upper(va_list types, char buffer[], 68 | int flags, int width, int precision, int size); 69 | 70 | int print_hexa(va_list types, char map_to[], 71 | char buffer[], int flags, char flag_ch, int width, int precision, int size); 72 | 73 | /* Function to print non printable characters */ 74 | int print_non_printable(va_list types, char buffer[], 75 | int flags, int width, int precision, int size); 76 | 77 | /* Funcion to print memory address */ 78 | int print_pointer(va_list types, char buffer[], 79 | int flags, int width, int precision, int size); 80 | 81 | /* Funciotns to handle other specifiers */ 82 | int get_flags(const char *format, int *i); 83 | int get_width(const char *format, int *i, va_list list); 84 | int get_precision(const char *format, int *i, va_list list); 85 | int get_size(const char *format, int *i); 86 | 87 | /*Function to print string in reverse*/ 88 | int print_reverse(va_list types, char buffer[], 89 | int flags, int width, int precision, int size); 90 | 91 | /*Function to print a string in rot 13*/ 92 | int print_rot13string(va_list types, char buffer[], 93 | int flags, int width, int precision, int size); 94 | 95 | /* width handler */ 96 | int handle_write_char(char c, char buffer[], 97 | int flags, int width, int precision, int size); 98 | int write_number(int is_positive, int ind, char buffer[], 99 | int flags, int width, int precision, int size); 100 | int write_num(int ind, char bff[], int flags, int width, int precision, 101 | int length, char padd, char extra_c); 102 | int write_pointer(char buffer[], int ind, int length, 103 | int width, int flags, char padd, char extra_c, int padd_start); 104 | 105 | int write_unsgnd(int is_negative, int ind, 106 | char buffer[], 107 | int flags, int width, int precision, int size); 108 | 109 | /****************** UTILS ******************/ 110 | int is_printable(char); 111 | int append_hexa_code(char, char[], int); 112 | int is_digit(char); 113 | 114 | long int convert_size_number(long int num, int size); 115 | long int convert_size_unsgnd(unsigned long int num, int size); 116 | 117 | #endif /* MAIN_H */ 118 | -------------------------------------------------------------------------------- /print_h_u.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | /************************* PRINT UNSIGNED NUMBER *************************/ 4 | /** 5 | * print_unsigned - Prints an unsigned number 6 | * @types: List a of arguments 7 | * @buffer: Buffer array to handle print 8 | * @flags: Calculates active flags 9 | * @width: get width 10 | * @precision: Precision specification 11 | * @size: Size specifier 12 | * Return: Number of chars printed. 13 | */ 14 | int print_unsigned(va_list types, char buffer[], 15 | int flags, int width, int precision, int size) 16 | { 17 | int i = BUFF_SIZE - 2; 18 | unsigned long int num = va_arg(types, unsigned long int); 19 | 20 | num = convert_size_unsgnd(num, size); 21 | 22 | if (num == 0) 23 | buffer[i--] = '0'; 24 | 25 | buffer[BUFF_SIZE - 1] = '\0'; 26 | 27 | while (num > 0) 28 | { 29 | buffer[i--] = (num % 10) + '0'; 30 | num /= 10; 31 | } 32 | 33 | i++; 34 | 35 | return (write_unsgnd(0, i, buffer, flags, width, precision, size)); 36 | } 37 | 38 | /************* PRINT UNSIGNED NUMBER IN OCTAL ****************/ 39 | /** 40 | * print_octal - Prints an unsigned number in octal notation 41 | * @types: Lista of arguments 42 | * @buffer: Buffer array to handle print 43 | * @flags: Calculates active flags 44 | * @width: get width 45 | * @precision: Precision specification 46 | * @size: Size specifier 47 | * Return: Number of chars printed 48 | */ 49 | int print_octal(va_list types, char buffer[], 50 | int flags, int width, int precision, int size) 51 | { 52 | 53 | int i = BUFF_SIZE - 2; 54 | unsigned long int num = va_arg(types, unsigned long int); 55 | unsigned long int init_num = num; 56 | 57 | UNUSED(width); 58 | 59 | num = convert_size_unsgnd(num, size); 60 | 61 | if (num == 0) 62 | buffer[i--] = '0'; 63 | 64 | buffer[BUFF_SIZE - 1] = '\0'; 65 | 66 | while (num > 0) 67 | { 68 | buffer[i--] = (num % 8) + '0'; 69 | num /= 8; 70 | } 71 | 72 | if (flags & F_HASH && init_num != 0) 73 | buffer[i--] = '0'; 74 | 75 | i++; 76 | 77 | return (write_unsgnd(0, i, buffer, flags, width, precision, size)); 78 | } 79 | 80 | /************** PRINT UNSIGNED NUMBER IN HEXADECIMAL **************/ 81 | /** 82 | * print_hexadecimal - Prints an unsigned number in hexadecimal notation 83 | * @types: Lista of arguments 84 | * @buffer: Buffer array to handle print 85 | * @flags: Calculates active flags 86 | * @width: get width 87 | * @precision: Precision specification 88 | * @size: Size specifier 89 | * Return: Number of chars printed 90 | */ 91 | int print_hexadecimal(va_list types, char buffer[], 92 | int flags, int width, int precision, int size) 93 | { 94 | return (print_hexa(types, "0123456789abcdef", buffer, 95 | flags, 'x', width, precision, size)); 96 | } 97 | 98 | /************* PRINT UNSIGNED NUMBER IN UPPER HEXADECIMAL **************/ 99 | /** 100 | * print_hexa_upper - Prints an unsigned number in upper hexadecimal notation 101 | * @types: Lista of arguments 102 | * @buffer: Buffer array to handle print 103 | * @flags: Calculates active flags 104 | * @width: get width 105 | * @precision: Precision specification 106 | * @size: Size specifier 107 | * Return: Number of chars printed 108 | */ 109 | int print_hexa_upper(va_list types, char buffer[], 110 | int flags, int width, int precision, int size) 111 | { 112 | return (print_hexa(types, "0123456789ABCDEF", buffer, 113 | flags, 'X', width, precision, size)); 114 | } 115 | 116 | /************** PRINT HEXX NUM IN LOWER OR UPPER **************/ 117 | /** 118 | * print_hexa - Prints a hexadecimal number in lower or upper 119 | * @types: Lista of arguments 120 | * @map_to: Array of values to map the number to 121 | * @buffer: Buffer array to handle print 122 | * @flags: Calculates active flags 123 | * @flag_ch: Calculates active flags 124 | * @width: get width 125 | * @precision: Precision specification 126 | * @size: Size specifier 127 | * @size: Size specification 128 | * Return: Number of chars printed 129 | */ 130 | int print_hexa(va_list types, char map_to[], char buffer[], 131 | int flags, char flag_ch, int width, int precision, int size) 132 | { 133 | int i = BUFF_SIZE - 2; 134 | unsigned long int num = va_arg(types, unsigned long int); 135 | unsigned long int init_num = num; 136 | 137 | UNUSED(width); 138 | 139 | num = convert_size_unsgnd(num, size); 140 | 141 | if (num == 0) 142 | buffer[i--] = '0'; 143 | 144 | buffer[BUFF_SIZE - 1] = '\0'; 145 | 146 | while (num > 0) 147 | { 148 | buffer[i--] = map_to[num % 16]; 149 | num /= 16; 150 | } 151 | 152 | if (flags & F_HASH && init_num != 0) 153 | { 154 | buffer[i--] = flag_ch; 155 | buffer[i--] = '0'; 156 | } 157 | 158 | i++; 159 | 160 | return (write_unsgnd(0, i, buffer, flags, width, precision, size)); 161 | } 162 | -------------------------------------------------------------------------------- /print_p_r_rot13.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | /****************** PRINT POINTER ******************/ 4 | /** 5 | * print_pointer - Prints the value of a pointer variable 6 | * @types: List a of arguments 7 | * @buffer: Buffer array to handle print 8 | * @flags: Calculates active flags 9 | * @width: get width 10 | * @precision: Precision specification 11 | * @size: Size specifier 12 | * Return: Number of chars printed. 13 | */ 14 | int print_pointer(va_list types, char buffer[], 15 | int flags, int width, int precision, int size) 16 | { 17 | char extra_c = 0, padd = ' '; 18 | int ind = BUFF_SIZE - 2, length = 2, padd_start = 1; /* length=2, for '0x' */ 19 | unsigned long num_addrs; 20 | char map_to[] = "0123456789abcdef"; 21 | void *addrs = va_arg(types, void *); 22 | 23 | UNUSED(width); 24 | UNUSED(size); 25 | 26 | if (addrs == NULL) 27 | return (write(1, "(nil)", 5)); 28 | 29 | buffer[BUFF_SIZE - 1] = '\0'; 30 | UNUSED(precision); 31 | 32 | num_addrs = (unsigned long)addrs; 33 | 34 | while (num_addrs > 0) 35 | { 36 | buffer[ind--] = map_to[num_addrs % 16]; 37 | num_addrs /= 16; 38 | length++; 39 | } 40 | 41 | if ((flags & F_ZERO) && !(flags & F_MINUS)) 42 | padd = '0'; 43 | if (flags & F_PLUS) 44 | extra_c = '+', length++; 45 | else if (flags & F_SPACE) 46 | extra_c = ' ', length++; 47 | 48 | ind++; 49 | 50 | /*return (write(1, &buffer[i], BUFF_SIZE - i - 1));*/ 51 | return (write_pointer(buffer, ind, length, 52 | width, flags, padd, extra_c, padd_start)); 53 | } 54 | 55 | /************************* PRINT NON PRINTABLE *************************/ 56 | /** 57 | * print_non_printable - Prints ascii codes in hexa of non printable chars 58 | * @types: Lista of arguments 59 | * @buffer: Buffer array to handle print 60 | * @flags: Calculates active flags 61 | * @width: get width 62 | * @precision: Precision specification 63 | * @size: Size specifier 64 | * Return: Number of chars printed 65 | */ 66 | int print_non_printable(va_list types, char buffer[], 67 | int flags, int width, int precision, int size) 68 | { 69 | int i = 0, offset = 0; 70 | char *str = va_arg(types, char *); 71 | 72 | UNUSED(flags); 73 | UNUSED(width); 74 | UNUSED(precision); 75 | UNUSED(size); 76 | 77 | if (str == NULL) 78 | return (write(1, "(null)", 6)); 79 | 80 | while (str[i] != '\0') 81 | { 82 | if (is_printable(str[i])) 83 | buffer[i + offset] = str[i]; 84 | else 85 | offset += append_hexa_code(str[i], buffer, i + offset); 86 | 87 | i++; 88 | } 89 | 90 | buffer[i + offset] = '\0'; 91 | 92 | return (write(1, buffer, i + offset)); 93 | } 94 | 95 | /************************* PRINT REVERSE *************************/ 96 | /** 97 | * print_reverse - Prints reverse string. 98 | * @types: Lista of arguments 99 | * @buffer: Buffer array to handle print 100 | * @flags: Calculates active flags 101 | * @width: get width 102 | * @precision: Precision specification 103 | * @size: Size specifier 104 | * Return: Numbers of chars printed 105 | */ 106 | 107 | int print_reverse(va_list types, char buffer[], 108 | int flags, int width, int precision, int size) 109 | { 110 | char *str; 111 | int i, count = 0; 112 | 113 | UNUSED(buffer); 114 | UNUSED(flags); 115 | UNUSED(width); 116 | UNUSED(size); 117 | 118 | str = va_arg(types, char *); 119 | 120 | if (str == NULL) 121 | { 122 | UNUSED(precision); 123 | 124 | str = ")Null("; 125 | } 126 | for (i = 0; str[i]; i++) 127 | ; 128 | 129 | for (i = i - 1; i >= 0; i--) 130 | { 131 | char z = str[i]; 132 | 133 | write(1, &z, 1); 134 | count++; 135 | } 136 | return (count); 137 | } 138 | /************************* PRINT A STRING IN ROT13 *************************/ 139 | /** 140 | * print_rot13string - Print a string in rot13. 141 | * @types: Lista of arguments 142 | * @buffer: Buffer array to handle print 143 | * @flags: Calculates active flags 144 | * @width: get width 145 | * @precision: Precision specification 146 | * @size: Size specifier 147 | * Return: Numbers of chars printed 148 | */ 149 | int print_rot13string(va_list types, char buffer[], 150 | int flags, int width, int precision, int size) 151 | { 152 | char x; 153 | char *str; 154 | unsigned int i, j; 155 | int count = 0; 156 | char in[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 157 | char out[] = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"; 158 | 159 | str = va_arg(types, char *); 160 | UNUSED(buffer); 161 | UNUSED(flags); 162 | UNUSED(width); 163 | UNUSED(precision); 164 | UNUSED(size); 165 | 166 | if (str == NULL) 167 | str = "(AHYY)"; 168 | for (i = 0; str[i]; i++) 169 | { 170 | for (j = 0; in[j]; j++) 171 | { 172 | if (in[j] == str[i]) 173 | { 174 | x = out[j]; 175 | write(1, &x, 1); 176 | count++; 177 | break; 178 | } 179 | } 180 | if (!in[j]) 181 | { 182 | x = str[i]; 183 | write(1, &x, 1); 184 | count++; 185 | } 186 | } 187 | return (count); 188 | } 189 | -------------------------------------------------------------------------------- /print_c_s.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | /************************* PRINT CHAR *************************/ 4 | 5 | /** 6 | * print_char - Prints a char 7 | * @types: List a of arguments 8 | * @buffer: Buffer array to handle print 9 | * @flags: Calculates active flags 10 | * @width: Width 11 | * @precision: Precision specification 12 | * @size: Size specifier 13 | * Return: Number of chars printed 14 | */ 15 | int print_char(va_list types, char buffer[], 16 | int flags, int width, int precision, int size) 17 | { 18 | char c = va_arg(types, int); 19 | 20 | return (handle_write_char(c, buffer, flags, width, precision, size)); 21 | } 22 | /************************* PRINT A STRING *************************/ 23 | /** 24 | * print_string - Prints a string 25 | * @types: List a of arguments 26 | * @buffer: Buffer array to handle print 27 | * @flags: Calculates active flags 28 | * @width: get width. 29 | * @precision: Precision specification 30 | * @size: Size specifier 31 | * Return: Number of chars printed 32 | */ 33 | int print_string(va_list types, char buffer[], 34 | int flags, int width, int precision, int size) 35 | { 36 | int length = 0, i; 37 | char *str = va_arg(types, char *); 38 | 39 | UNUSED(buffer); 40 | UNUSED(flags); 41 | UNUSED(width); 42 | UNUSED(precision); 43 | UNUSED(size); 44 | if (str == NULL) 45 | { 46 | str = "(null)"; 47 | if (precision >= 6) 48 | str = " "; 49 | } 50 | 51 | while (str[length] != '\0') 52 | length++; 53 | 54 | if (precision >= 0 && precision < length) 55 | length = precision; 56 | 57 | if (width > length) 58 | { 59 | if (flags & F_MINUS) 60 | { 61 | write(1, &str[0], length); 62 | for (i = width - length; i > 0; i--) 63 | write(1, " ", 1); 64 | return (width); 65 | } 66 | else 67 | { 68 | for (i = width - length; i > 0; i--) 69 | write(1, " ", 1); 70 | write(1, &str[0], length); 71 | return (width); 72 | } 73 | } 74 | 75 | return (write(1, str, length)); 76 | } 77 | /************************* PRINT PERCENT SIGN *************************/ 78 | /** 79 | * print_percent - Prints a percent sign 80 | * @types: Lista of arguments 81 | * @buffer: Buffer array to handle print 82 | * @flags: Calculates active flags 83 | * @width: get width. 84 | * @precision: Precision specification 85 | * @size: Size specifier 86 | * Return: Number of chars printed 87 | */ 88 | int print_percent(va_list types, char buffer[], 89 | int flags, int width, int precision, int size) 90 | { 91 | UNUSED(types); 92 | UNUSED(buffer); 93 | UNUSED(flags); 94 | UNUSED(width); 95 | UNUSED(precision); 96 | UNUSED(size); 97 | return (write(1, "%%", 1)); 98 | } 99 | 100 | /************************* PRINT INT *************************/ 101 | /** 102 | * print_int - Print int 103 | * @types: Lista of arguments 104 | * @buffer: Buffer array to handle print 105 | * @flags: Calculates active flags 106 | * @width: get width. 107 | * @precision: Precision specification 108 | * @size: Size specifier 109 | * Return: Number of chars printed 110 | */ 111 | int print_int(va_list types, char buffer[], 112 | int flags, int width, int precision, int size) 113 | { 114 | int i = BUFF_SIZE - 2; 115 | int is_negative = 0; 116 | long int n = va_arg(types, long int); 117 | unsigned long int num; 118 | 119 | n = convert_size_number(n, size); 120 | 121 | if (n == 0) 122 | buffer[i--] = '0'; 123 | 124 | buffer[BUFF_SIZE - 1] = '\0'; 125 | num = (unsigned long int)n; 126 | 127 | if (n < 0) 128 | { 129 | num = (unsigned long int)((-1) * n); 130 | is_negative = 1; 131 | } 132 | 133 | while (num > 0) 134 | { 135 | buffer[i--] = (num % 10) + '0'; 136 | num /= 10; 137 | } 138 | 139 | i++; 140 | 141 | return (write_number(is_negative, i, buffer, flags, width, precision, size)); 142 | } 143 | 144 | /************************* PRINT BINARY *************************/ 145 | /** 146 | * print_binary - Prints an unsigned number 147 | * @types: Lista of arguments 148 | * @buffer: Buffer array to handle print 149 | * @flags: Calculates active flags 150 | * @width: get width. 151 | * @precision: Precision specification 152 | * @size: Size specifier 153 | * Return: Numbers of char printed. 154 | */ 155 | int print_binary(va_list types, char buffer[], 156 | int flags, int width, int precision, int size) 157 | { 158 | unsigned int n, m, i, sum; 159 | unsigned int a[32]; 160 | int count; 161 | 162 | UNUSED(buffer); 163 | UNUSED(flags); 164 | UNUSED(width); 165 | UNUSED(precision); 166 | UNUSED(size); 167 | 168 | n = va_arg(types, unsigned int); 169 | m = 2147483648; /* (2 ^ 31) */ 170 | a[0] = n / m; 171 | for (i = 1; i < 32; i++) 172 | { 173 | m /= 2; 174 | a[i] = (n / m) % 2; 175 | } 176 | for (i = 0, sum = 0, count = 0; i < 32; i++) 177 | { 178 | sum += a[i]; 179 | if (sum || i == 31) 180 | { 181 | char z = '0' + a[i]; 182 | 183 | write(1, &z, 1); 184 | count++; 185 | } 186 | } 187 | return (count); 188 | } 189 | -------------------------------------------------------------------------------- /print_write.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | /************************* WRITE HANDLE *************************/ 4 | /** 5 | * handle_write_char - Prints a string 6 | * @c: char types. 7 | * @buffer: Buffer array to handle print 8 | * @flags: Calculates active flags. 9 | * @width: get width. 10 | * @precision: precision specifier 11 | * @size: Size specifier 12 | * 13 | * Return: Number of chars printed. 14 | */ 15 | int handle_write_char(char c, char buffer[], 16 | int flags, int width, int precision, int size) 17 | { /* char is stored at left and paddind at buffer's right */ 18 | int i = 0; 19 | char padd = ' '; 20 | 21 | UNUSED(precision); 22 | UNUSED(size); 23 | 24 | if (flags & F_ZERO) 25 | padd = '0'; 26 | 27 | buffer[i++] = c; 28 | buffer[i] = '\0'; 29 | 30 | if (width > 1) 31 | { 32 | buffer[BUFF_SIZE - 1] = '\0'; 33 | for (i = 0; i < width - 1; i++) 34 | buffer[BUFF_SIZE - i - 2] = padd; 35 | 36 | if (flags & F_MINUS) 37 | return (write(1, &buffer[0], 1) + 38 | write(1, &buffer[BUFF_SIZE - i - 1], width - 1)); 39 | else 40 | return (write(1, &buffer[BUFF_SIZE - i - 1], width - 1) + 41 | write(1, &buffer[0], 1)); 42 | } 43 | 44 | return (write(1, &buffer[0], 1)); 45 | } 46 | 47 | /************************* WRITE NUMBER *************************/ 48 | /** 49 | * write_number - Prints a string 50 | * @is_negative: Lista of arguments 51 | * @ind: char types. 52 | * @buffer: Buffer array to handle print 53 | * @flags: Calculates active flags 54 | * @width: get width. 55 | * @precision: precision specifier 56 | * @size: Size specifier 57 | * 58 | * Return: Number of chars printed. 59 | */ 60 | int write_number(int is_negative, int ind, char buffer[], 61 | int flags, int width, int precision, int size) 62 | { 63 | int length = BUFF_SIZE - ind - 1; 64 | char padd = ' ', extra_ch = 0; 65 | 66 | UNUSED(size); 67 | 68 | if ((flags & F_ZERO) && !(flags & F_MINUS)) 69 | padd = '0'; 70 | if (is_negative) 71 | extra_ch = '-'; 72 | else if (flags & F_PLUS) 73 | extra_ch = '+'; 74 | else if (flags & F_SPACE) 75 | extra_ch = ' '; 76 | 77 | return (write_num(ind, buffer, flags, width, precision, 78 | length, padd, extra_ch)); 79 | } 80 | 81 | /** 82 | * write_num - Write a number using a bufffer 83 | * @ind: Index at which the number starts on the buffer 84 | * @buffer: Buffer 85 | * @flags: Flags 86 | * @width: width 87 | * @prec: Precision specifier 88 | * @length: Number length 89 | * @padd: Pading char 90 | * @extra_c: Extra char 91 | * 92 | * Return: Number of printed chars. 93 | */ 94 | int write_num(int ind, char buffer[], 95 | int flags, int width, int prec, 96 | int length, char padd, char extra_c) 97 | { 98 | int i, padd_start = 1; 99 | 100 | if (prec == 0 && ind == BUFF_SIZE - 2 && buffer[ind] == '0' && width == 0) 101 | return (0); /* printf(".0d", 0) no char is printed */ 102 | if (prec == 0 && ind == BUFF_SIZE - 2 && buffer[ind] == '0') 103 | buffer[ind] = padd = ' '; /* width is displayed with padding ' ' */ 104 | if (prec > 0 && prec < length) 105 | padd = ' '; 106 | while (prec > length) 107 | buffer[--ind] = '0', length++; 108 | if (extra_c != 0) 109 | length++; 110 | if (width > length) 111 | { 112 | for (i = 1; i < width - length + 1; i++) 113 | buffer[i] = padd; 114 | buffer[i] = '\0'; 115 | if (flags & F_MINUS && padd == ' ')/* Asign extra char to left of buffer */ 116 | { 117 | if (extra_c) 118 | buffer[--ind] = extra_c; 119 | return (write(1, &buffer[ind], length) + write(1, &buffer[1], i - 1)); 120 | } 121 | else if (!(flags & F_MINUS) && padd == ' ')/* extra char to left of buff */ 122 | { 123 | if (extra_c) 124 | buffer[--ind] = extra_c; 125 | return (write(1, &buffer[1], i - 1) + write(1, &buffer[ind], length)); 126 | } 127 | else if (!(flags & F_MINUS) && padd == '0')/* extra char to left of padd */ 128 | { 129 | if (extra_c) 130 | buffer[--padd_start] = extra_c; 131 | return (write(1, &buffer[padd_start], i - padd_start) + 132 | write(1, &buffer[ind], length - (1 - padd_start))); 133 | } 134 | } 135 | if (extra_c) 136 | buffer[--ind] = extra_c; 137 | return (write(1, &buffer[ind], length)); 138 | } 139 | 140 | /** 141 | * write_unsgnd - Writes an unsigned number 142 | * @is_negative: Number indicating if the num is negative 143 | * @ind: Index at which the number starts in the buffer 144 | * @buffer: Array of chars 145 | * @flags: Flags specifiers 146 | * @width: Width specifier 147 | * @precision: Precision specifier 148 | * @size: Size specifier 149 | * 150 | * Return: Number of written chars. 151 | */ 152 | int write_unsgnd(int is_negative, int ind, 153 | char buffer[], 154 | int flags, int width, int precision, int size) 155 | { 156 | /* The number is stored at the bufer's right and starts at position i */ 157 | int length = BUFF_SIZE - ind - 1, i = 0; 158 | char padd = ' '; 159 | 160 | UNUSED(is_negative); 161 | UNUSED(size); 162 | 163 | if (precision == 0 && ind == BUFF_SIZE - 2 && buffer[ind] == '0') 164 | return (0); /* printf(".0d", 0) no char is printed */ 165 | 166 | if (precision > 0 && precision < length) 167 | padd = ' '; 168 | 169 | while (precision > length) 170 | { 171 | buffer[--ind] = '0'; 172 | length++; 173 | } 174 | 175 | if ((flags & F_ZERO) && !(flags & F_MINUS)) 176 | padd = '0'; 177 | 178 | if (width > length) 179 | { 180 | for (i = 0; i < width - length; i++) 181 | buffer[i] = padd; 182 | 183 | buffer[i] = '\0'; 184 | 185 | if (flags & F_MINUS) /* Asign extra char to left of buffer [buffer>padd]*/ 186 | { 187 | return (write(1, &buffer[ind], length) + write(1, &buffer[0], i)); 188 | } 189 | else /* Asign extra char to left of padding [padd>buffer]*/ 190 | { 191 | return (write(1, &buffer[0], i) + write(1, &buffer[ind], length)); 192 | } 193 | } 194 | 195 | return (write(1, &buffer[ind], length)); 196 | } 197 | 198 | /** 199 | * write_pointer - Write a memory address 200 | * @buffer: Arrays of chars 201 | * @ind: Index at which the number starts in the buffer 202 | * @length: Length of number 203 | * @width: Wwidth specifier 204 | * @flags: Flags specifier 205 | * @padd: Char representing the padding 206 | * @extra_c: Char representing extra char 207 | * @padd_start: Index at which padding should start 208 | * 209 | * Return: Number of written chars. 210 | */ 211 | int write_pointer(char buffer[], int ind, int length, 212 | int width, int flags, char padd, char extra_c, int padd_start) 213 | { 214 | int i; 215 | 216 | if (width > length) 217 | { 218 | for (i = 3; i < width - length + 3; i++) 219 | buffer[i] = padd; 220 | buffer[i] = '\0'; 221 | if (flags & F_MINUS && padd == ' ')/* Asign extra char to left of buffer */ 222 | { 223 | buffer[--ind] = 'x'; 224 | buffer[--ind] = '0'; 225 | if (extra_c) 226 | buffer[--ind] = extra_c; 227 | return (write(1, &buffer[ind], length) + write(1, &buffer[3], i - 3)); 228 | } 229 | else if (!(flags & F_MINUS) && padd == ' ')/* extra char to left of buffer */ 230 | { 231 | buffer[--ind] = 'x'; 232 | buffer[--ind] = '0'; 233 | if (extra_c) 234 | buffer[--ind] = extra_c; 235 | return (write(1, &buffer[3], i - 3) + write(1, &buffer[ind], length)); 236 | } 237 | else if (!(flags & F_MINUS) && padd == '0')/* extra char to left of padd */ 238 | { 239 | if (extra_c) 240 | buffer[--padd_start] = extra_c; 241 | buffer[1] = '0'; 242 | buffer[2] = 'x'; 243 | return (write(1, &buffer[padd_start], i - padd_start) + 244 | write(1, &buffer[ind], length - (1 - padd_start) - 2)); 245 | } 246 | } 247 | buffer[--ind] = 'x'; 248 | buffer[--ind] = '0'; 249 | if (extra_c) 250 | buffer[--ind] = extra_c; 251 | return (write(1, &buffer[ind], BUFF_SIZE - ind - 1)); 252 | } 253 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![logo](https://github.com/Solomonkassa/Solomonkassa/blob/main/hello-world.gif) 2 | 3 | # printf 4 | 5 | ### Description 6 | 7 | -------------- 8 | 9 | 10 | The printf function sends formatted output to stdout. 11 | A custom _printf() for learning purposes was developed by cohort #11 students Solomon kassa and Nawwal Ismael. 12 | _printf() function format string is a character string, beginning and ending in its initial shift state, if any. 13 | These arguments are placed using the percentage '%' operator. 14 | 15 | ------------ 16 | 17 | 18 | #### Resources 19 | 20 | ------------ 21 | 22 | 23 | Secrets of printfby Don colton 24 | https://www.cypress.com/file/54761/download 25 | 26 | ------------ 27 | 28 | 29 | 30 | #### Authorized functions and macros 31 | 32 | ------------ 33 | 34 | 35 | write (man 2 write) 36 | malloc (man 3 malloc) 37 | free (man 3 free) 38 | va_start (man 3 va_start) 39 | va_end (man 3 va_end) 40 | va_copy (man 3 va_copy) 41 | va_arg (man 3 va_arg) 42 | 43 | ------------ 44 | 45 | #### Compilation 46 | 47 | ------------ 48 | 49 | 50 | 51 | The code must be compiled this way: 52 | 53 | **$ gcc -Wall -Werror -Wextra -pedantic *.c** 54 | 55 | As a consequence, be careful not to push any c file containing a main function in the root directory of your project (you could have a test folder containing all your tests files including main functions) 56 | 57 | The main files will include your main header file (main.h): **#include main.h** 58 | 59 | ------------ 60 | 61 | #### Use & Examples 62 | 63 | 64 | ------------ 65 | 66 | **Prototype:** int _printf(const char *format, ...); 67 | **Use - General:** _printf("format string", var1, var2, ...); 68 | 69 | **Examples:** 70 | - Basic String: _printf("%s World", "Hello");` 71 | - Output: Hello World 72 | 73 | - Print integers: _printf("This is an array element: arr[%d]:%c", 32, arr[32]);` 74 | - Output: This is an array element arr[32]:A 75 | 76 | Many other specifiers and flags were added and by combinig those the _printf() function generate a different ouput. The following list are the specifiers and flags allowed. 77 | 78 | ------------ 79 | 80 | #### Use & Examples 81 | 82 | 83 | ------------ 84 | 85 | ###### Specifiers 86 | 87 | Specifier |Output |Examples | 88 | |----------------|-------------------------------|-----------------------------| 89 | | `c` | Character | y | 90 | | `d` or `i` | Signed integer | 1024, -1024 | 91 | | `s` | String of characters | Hello World | 92 | | `b` | Binary Representation of unsigned integer | 01010110 | 93 | | `u` | Unsigned integer | 1024 | 94 | | `o` | Unsigned octal | 432 | 95 | | `x` | Unsigned hexadecimal integer | 3ca | 96 | | `X` | Unsigned hexadecimal integer (uppercase) | 3CA | 97 | | `S` | String with hex-ascii value replacing special chars | \x0A\x0A | 98 | | `p` | Pointer address | 0x403212 | 99 | | `r` | Reversed string of characters | dlroW olleH | 100 | | `R` | ROT13 Translation of string | Uryyb | 101 | 102 | ###### Flags (In development...) 103 | 104 | |Flag |Description | 105 | |----------------|-------------------------------| 106 | | `-` |Left-justify the output within the field width that was given; Right justification is the default (see _width_ sub-specifier). | 107 | | `+` |Preceeds the result with a plus or minus sign (`+` or `-`) even for positive numbers. By default, only negative numbers are preceded with a `-` sign. | 108 | | `(space)` |If no sign is going to be written, a blank space is inserted before the value. | 109 | | `#` |Used with `o`, `x` or `X` specifiers the value is preceeded with 0, 0x or 0X respectively for values different than zero. | 110 | | `0` |Left-pads the number with zeroes (`0`) instead of spaces when padding is specified (see _width_ sub-specifier). | 111 | 112 | ###### Width (In development...) 113 | 114 | |Width |Description | 115 | |----------------|-------------------------------| 116 | | `(number)` |Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.| 117 | | `*` | The _width_ is not specified in the _format_ string, but as an additional integer value argument preceding the argument that has to be formatted.| 118 | 119 | ### Precision (In development...) 120 | 121 | |.Precision |Description | 122 | |----------------|-------------------------------| 123 | | `.(number)` |**For integer specifiers (`d`, `i`, `o`, `u`, `x`, `X`):** _precision_ specifies the minimum number of digits to be written. If the value to be written is shorter than this number, the result is padded with leading zeros. The value is not truncated even if the result is longer. A _precision_ of 0 means that no character is written for the value 0. **For `s`**: this is the maximum number of characters to be printed. By default all characters are printed until the ending null character is encountered. If the period is specified without an explicit value for _precision_, 0 is assumed. | 124 | 125 | ### Lenght modifiers (In development...) 126 | 127 | |Modifier/Specifier |`d` & `i` |`u`, `o`, `x`, `X` |`c` |`s` |`p` | 128 | |----------------|---------|------------|-------------|-----|-------| 129 | | `none` | int |unsigned int | int| char pointer| void pointer | 130 | | `h` |short int|unsigned short int | | | | 131 | | `l` |long int |unsigned long int | | | | 132 | 133 | ------------ 134 | 135 | #### Files contained in this repository 136 | 137 | 138 | ------------ 139 | 140 | |Name |Information |Relevant Files | 141 | |----------------|-------------------------------|-----------------------------| 142 | |`man_3_printf`|Man page of the _printf() function.| `None` | 143 | |`main.h` | Header file with the data type struct, standard libraries and custom prototypes.| `*.c compilation` | 144 | |`_printf.c`|Main printf function file. Calls other functions.|`printf_(name of var).c file` | 145 | |`printf_c_s.c`|Contains character & string print function.|`None` | 146 | |`printf_h_u.c` | Contains decimal & unsigned integer functions. | `None` | 147 | | | Functions that returns octal number. | `None` | 148 | | | Calls hexadecimal numbers (Uppercase). | `None` | 149 | | | Calls hexadecimal numbers (lowercase). | `None` | 150 | |`print_flag.c` | Functions that get flags. | `None` | 151 | |`print_precision.c` | function get percisions | `None` | 152 | |`print_width.c` | function print width. | `None` | 153 | |`print_size.c` | function print size. | `None` | 154 | |`print_handle.c` | function handle pointer . | `None` | 155 | |`write_handle.c` | functions handle character | `none` | 156 | | |function write number . | `none` | 157 | |`print_p_r_rot13.c` | function print pointer. | `none` | 158 | | | function print non printable. | `None` | 159 | |`printf_rot13.c` | function print rot13. | `None` | 160 | | | function print reverse. | `None` | 161 | |`_putchar.c` | Custom putchar function. | `None` | 162 | 163 | 164 | ------------ 165 | 166 | #### Tasks required for this project 167 | 168 | 169 | ------------ 170 | 171 | 0. ###### I am not going anywhere. You can print that wherever you want to. I'm here and I am a Spur for life1. I am not going anywhere. You can print that wherever you want to. I'm here and I am a Spur for life. 172 | Write a function that produces output according to a format. 173 | Handle the following conversion specifiers: 174 | - c 175 | - s 176 | - % 177 | 178 | 1. ###### Education is when you read the fine print. Experience is what you get if you dont 179 | Handle the following conversion specifiers: 180 | - d 181 | - i 182 | 183 | 2. ###### With a face like mine, I do better in print 184 | Handle the following conversion specifiers: 185 | - b 186 | 187 | 3. ###### What one has not experienced, one will never understand in print 188 | Handle the following conversion specifiers: 189 | - u 190 | - x 191 | - o 192 | - x 193 | - X 194 | 195 | 4. ###### Nothing in fine print is ever good news 196 | Use a local buffer of 1024 chars in order to call write as little as possible. 197 | 198 | 5. ###### Handle the following custom conversion specifier 199 | - S : prints the string. 200 | - 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). 201 | 202 | 6. ###### How is the world ruled and led to war? Diplomats lie to journalists and believe these lies when they see them in print 203 | Handle the following conversion specifier: p 204 | 205 | 7. ###### The big print gives and the small print takes away 206 | Handle the following flag characters for non-custom conversion specifiers: 207 | - ´+´ 208 | - space 209 | - ´#´ 210 | 211 | 8. ###### Sarcasm is lost in print 212 | Handle the following length modifiers for non-custom conversion specifiers: 213 | - l 214 | - h 215 | Conversion specifiers to handle: d, i, u, o, x, X 216 | 217 | 9. ###### Print some money and give it to us for the rain forests 218 | Handle the field width for non-custom conversion specifiers. 219 | 220 | 10. ###### The negative is the equivalent of the composer's score, and the print the performance 221 | Handle the precision for non-custom conversion specifiers. 222 | 223 | 11. ###### It's depressing when you're still around and your albums are out of print 224 | Handle the 0 flag character for non-custom conversion specifiers. 225 | 226 | 12. ###### Every time that I wanted to give up, if I saw an interesting textile, print what ever, suddenly I would see a collection 227 | Handle the - flag character for non-custom conversion specifiers. 228 | 229 | 13. ###### Print is the sharpest and the strongest weapon of our party 230 | Handle the following custom conversion specifier: 231 | - r : prints the reversed string 232 | 233 | 14. ###### The flood of print has turned reading into a process of gulping rather than savoring 234 | Handle the following custom conversion specifier: 235 | - R: prints the rot13'ed string 236 | 237 | 15. ###### * 238 | All the above options work well together. 239 | 240 | ### Authors © 241 | 242 | - Solomon Kassa 243 | - Nawwal Ismael 244 | 245 | 246 | --------------------------------------------------------------------------------