Algorithms_in_C 1.0.0
Set of algorithms implemented in C.
min_printf.h File Reference

Implementation of a function similar to printf More...

#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
Include dependency graph for min_printf.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  buffer
 struct used to store character in certain times More...
 

Macros

#define INT_MAX_LENGTH   10
 for malloc and free functions for write function for va_start and va_arg functions
 
#define PRECISION_FOR_FLOAT   8
 

Typedefs

typedef struct buffer Buffer
 struct used to store character in certain times
 

Functions

int power_of_ten (int a)
 
int is_number (char *c)
 Checks if a character is a number. More...
 
char get_ch (char *p, Buffer *buffer)
 Returns specific required next character. More...
 
void unget_ch (char *c, Buffer *buffer)
 Stores character to the buffer->buffr_char More...
 
int get_number_of_digits (int n)
 Calculates the number of digits in a number. More...
 
void put_char (char s)
 Prints one character on screen. More...
 
void reverse_str (char *p)
 Reverses a string using two pointer algorithm More...
 
void print_int_value (int n, int width, int precision)
 
void print_double_value (double dval, int width, int precision)
 The algorithm here is also the same as the print_int_value function. More...
 
void print_string (char *p, int width, int precision)
 
char * get_width_and_precision (char *p, Buffer *buffer, int *width, int *precision)
 Takes width and precision specified from the format of the string. More...
 
void min_printf (char *fmt,...)
 min_printf is the function same as printf More...
 

Detailed Description

Implementation of a function similar to printf

printf statement rewritten (as min_printf) in C without using the stdio.h library Syntax of min_printf is same as printf Currently min_printf handles: Integers, Doubles, floats, characters and strings The format specifiers and escape sequence is the same as for printf User can also specify the width and precision if required, just like in the case of printf How to use it:

Function Documentation

◆ get_ch()

char get_ch ( char *  p,
Buffer buffer 
)

Returns specific required next character.

Parameters
ppointer to a format string of min_printf()
bufferstruct for checking if buffr_char character is present or not
Returns
character inside buffer->buffr_char, if buffer->buf_size is one
character at which p is pointing, if buffer->buf_size is zero

< Since character is used, this sets buffer->buf_size to zero

71{
72 if (buffer->buf_size) {
73 buffer->buf_size = 0; ///< Since character is used, this sets `buffer->buf_size` to zero
74 return buffer->buffr_char; // Returns character inside buffer->buffr_char
75 }
76 return *p++;
77}
struct used to store character in certain times
Definition: min_printf.h:31

◆ get_number_of_digits()

int get_number_of_digits ( int  n)

Calculates the number of digits in a number.

Parameters
nnumber whose digits are to be counted
Returns
number of digits in n
97{
98 int digits = 0; // Stores encountered number of digits
99 while (n > 0) {
100 ++digits; // Since number still contains a digit, so increment digit variable
101 n /= 10; // Removes last digit from number
102 }
103 return digits;
104}

◆ get_width_and_precision()

char * get_width_and_precision ( char *  p,
Buffer buffer,
int *  width,
int *  precision 
)

Takes width and precision specified from the format of the string.

Parameters
ppointer of the format string
widthvariable in which width will be stored
precisionvariable in which precision will be stored
Returns
character pointer to the current pointer of string p (used to update value of p)
272{
273 /* Skip % if p is pointing to it.*/
274 if (*p == '%')
275 ++p;
276
277 /* Calculates the width specified. */
278 while (*p != '.' && is_number(p))
279 *width = *width * 10 + (*p++ - '0');
280
281 /* Calculates the precision specified.*/
282 if (*p == '.' /* Since a precision is always specified after a '.'. */) {
283 while (is_number(++p))
284 *precision = *precision * 10 + (*p - '0');
285 unget_ch(p, buffer); // The non number will be stored in `buffer->buffr`
286 }
287 return p;
288}
void unget_ch(char *c, Buffer *buffer)
Stores character to the buffer->buffr_char
Definition: min_printf.h:84
int is_number(char *c)
Checks if a character is a number.
Definition: min_printf.h:58
Here is the call graph for this function:

◆ is_number()

int is_number ( char *  c)

Checks if a character is a number.

Parameters
ccharacter to be checked if it's a number or not
Returns
true(1) if the character is a number
false(0) if the character is NOT a number
59{
60 return (*c >= '0' && *c <= '9') ? 1 : 0;
61}

◆ min_printf()

void min_printf ( char *  fmt,
  ... 
)

min_printf is the function same as printf

Parameters
fmtformat of string
...arguments passed according to the format
296{
297 va_list ap; // Points to each unnamed arg in turn
298 char *p, *sval; // p will be used to point to fmt and sval will store string value
299 char cval; // Stores character value
300 int ival; // For integer values
301 double dval; // For double or float values
302 va_start(ap, fmt); // Makes ap points to first unnames argument
303
304 /* Initializing the buffer for storing character. */
305 Buffer *buffer = (Buffer *) malloc(sizeof(Buffer));
306 buffer->buf_size = 0; // Initially set buffer size to zero as no character is inserted
307
308 for (p = fmt; *p != '\0'; ++p) {
309
310 /* If p != '%' then the character is printed to screen. */
311 if (*p != '%') {
312 put_char(*p);
313 continue;
314 }
315
316 int width = 0; // Stores width specified
317 int precision = 0; // Stores precision specified
318
319 /* Updates values of width, precision and p. */
320 p = get_width_and_precision(p, buffer, &width, &precision);
321
322 /* Checks format of next argument.*/
323 switch (get_ch(p, buffer)) {
324 case 'd': // Integer
325 ival = va_arg(ap, int);
326 print_int_value(ival, width, precision);
327 break;
328 case 'c': // Character
329 cval = va_arg(ap, int);
330 put_char(cval);
331 break;
332 case 'f': // Float or Double
333 dval = va_arg(ap, double);
334
335 // If precision is not specified then default value is applied
336 if (precision == 0)
337 precision = PRECISION_FOR_FLOAT;
338 print_double_value(dval, width, precision);
339 break;
340 case 's': // String pointer
341 sval = va_arg(ap, char *);
342 print_string(sval, width, precision);
343 break;
344 default:
345 put_char(*p);
346 break;
347 }
348 }
349 va_end(ap);
350}
#define malloc(bytes)
This macro replace the standard malloc function with malloc_dbg.
Definition: malloc_dbg.h:18
void print_int_value(int n, int width, int precision)
Definition: min_printf.h:154
char get_ch(char *p, Buffer *buffer)
Returns specific required next character.
Definition: min_printf.h:70
void print_double_value(double dval, int width, int precision)
The algorithm here is also the same as the print_int_value function.
Definition: min_printf.h:206
char * get_width_and_precision(char *p, Buffer *buffer, int *width, int *precision)
Takes width and precision specified from the format of the string.
Definition: min_printf.h:271
void put_char(char s)
Prints one character on screen.
Definition: min_printf.h:110
void print_string(char *p, int width, int precision)
Definition: min_printf.h:234
Here is the call graph for this function:

◆ power_of_ten()

int power_of_ten ( int  a)

This function return ten to the power a(The parameter specified to it) like: if the parameter specified is 4 i.e. -> power_of_ten(4) is called then this function will return ten to the power four (10000);

Parameters
aThe power of ten which is to be returned
Returns
Ten to the power a

< This number will be returned as ten to power of a

45{
46 int n = 1; ///< This number will be returned as ten to power of a
47 for (int i = 1; i <= a; ++i)
48 n *= 10 ;
49 return n;
50}

◆ print_double_value()

void print_double_value ( double  dval,
int  width,
int  precision 
)

The algorithm here is also the same as the print_int_value function.

First, the digits before decimal is printed by converting the double to int. Then after printed a ., the double number is subtracted with the integer value of the number, leaving us with 0 before the decimal. Then, we multiply the number with 10 raised to the power precision ( precision means how many digits to be printed after the decimal.) By default, the precision is 8 if it is not specified. Then, the remaining number is printed on the screen.

Parameters
dvaldouble number to be printed
widthsimilar to width parameter of print_int_value()
precisiontells the number of digits to be printed after the decimal (By default it is 8)
207{
208 int ndigits = get_number_of_digits((int) dval); // Store number of digits before decimal in dval
209 int reqd_blanks = width - (precision + 1) - ndigits; // Blanks to be printed before printing dval, just to cover the width
210
211 print_int_value((int) dval, reqd_blanks, 0); // Prints the part before decimal
212
213 put_char('.'); // Print decimal
214
215 /*Deletes digits before decimal and makes them zero. For example:
216 if dval = 1923.79022, them this will make dval = 0.79022
217 */
218 dval = dval - (int) dval;
219
220 dval *= power_of_ten(precision); // Brings precision number of digits after decimal to before decimal
221
222 print_int_value((int) dval, 0, precision); // Prints the remaining number
223}
int power_of_ten(int a)
Definition: min_printf.h:44
int get_number_of_digits(int n)
Calculates the number of digits in a number.
Definition: min_printf.h:96
Here is the call graph for this function:

◆ print_int_value()

void print_int_value ( int  n,
int  width,
int  precision 
)

The algorithm here is to first convert the number into string and then reverse it be passing it to reverse_str function and then printing on the screen

Parameters
nNumber to be printed
widthTotal characters to be printed (Prints ' ' if (size < width)
precisionTotal character of number to be printed (prints 0 before number if size of number < precision)

< Used to store number of digits in number

The next two conditions check weather it is required to add blanks before printing the number (ie: width)and is it specified how many zeros to be printed before the number is printed (ie: precision)

155{
156 char *p = (char *) malloc(INT_MAX_LENGTH * sizeof(char) + 1); /* +1 for '\0' */
157 char *s = p; // Temporary pointer
158 int size = 0; //!< Used to store number of digits in number
159
160 while (n > 0) {
161 *s++ = n % 10 + '0'; // Converts last digit of number to character and store it in p
162 ++size; // Increment size variable as one more digit is occured
163 n /= 10; // Removes the last digit from the number n as we have successfully stored it in p
164 }
165 *s = '\0';
166
167 s = p; // Again point back s to starting of p
168
169 reverse_str(p);
170
171 /*!
172 * The next two conditions check weather it is required to
173 * add blanks before printing the number (ie: width)and is it specified how many
174 * zeros to be printed before the number is printed (ie: precision)
175 */
176 if (width > 0 && size < width)
177 for (int i = 0; i < (width - precision); ++i)
178 put_char(' ');
179
180 if (precision > 0 && precision > size)
181 for (int i = 0; i < (precision - size); ++i)
182 put_char('0');
183
184 /* Prints the number.*/
185 while (*s != '\0')
186 put_char(*s++);
187
188 free(p);
189}
#define free(ptr)
This macro replace the standard free function with free_dbg.
Definition: malloc_dbg.h:26
void reverse_str(char *p)
Reverses a string using two pointer algorithm
Definition: min_printf.h:124
#define INT_MAX_LENGTH
for malloc and free functions for write function for va_start and va_arg functions
Definition: min_printf.h:25
Here is the call graph for this function:

◆ print_string()

void print_string ( char *  p,
int  width,
int  precision 
)

First size of the string is calculated to check whether width and precision are to be taken into account or not. Then, the string is printed in accordingly.

Parameters
ppointer to string to be printed
widthif (width > sizeof string) then, blanks will be printed before sting to cover up the width
precisiontotal characters of the string to be printed (prints the whole string if 0 or greater than size of string)
235{
236 int size = 0; // Stores number of character in string
237 char *s = p; // Temporary pointer
238
239 /* Calculates size of string p*/
240 while (*s != '\0') {
241 ++size;
242 ++s;
243 }
244
245 s = p; // Point s to starting of p
246
247 /* Checks how many characters to be printed.
248 if precision is defined then size variable is changed to precision so that only precision
249 number of characters were printed.
250 */
251 if (precision != 0 && precision < size)
252 size = precision;
253
254 /* Prints blanks to cover the width if required*/
255 for (int i = 0; i < (width - size); ++i)
256 put_char(' ');
257
258 /* Print the string.*/
259 for (int i = 0; i < size; ++i)
260 put_char(*s++);
261
262}
Here is the call graph for this function:

◆ put_char()

void put_char ( char  s)

Prints one character on screen.

Parameters
scharacter to be printed on the screen
111{
112 /* buf used for storing character to be printed in an array (+1 for '\0')*/
113 char *buf = (char *) malloc(sizeof(char) + 1);
114 *buf = s;
115 *(buf + 1) = '\0';
116 write(1, buf, 1);
117 free(buf);
118}

◆ reverse_str()

void reverse_str ( char *  p)

Reverses a string using two pointer algorithm

Parameters
ppointer to the string which is to be reversed
125{
126 char *l = p; // Points to first character of p
127 char *h = p; // Will be used to point to last character of p
128 char temp; // Temporarily stores a character, Used in swapping
129
130 while (*h != '\0')
131 ++h;
132 --h; // Now h point to last valid character of string
133
134 /* Swap character which lower and higher are pointing until lower < higher. At that point string will be reversed.*/
135 while (l < h) {
136 temp = *l;
137 *l = *h;
138 *h = temp;
139 ++l; // Increment lower to next character
140 --h; // Decrement higher to previous character from current character
141 }
142}

◆ unget_ch()

void unget_ch ( char *  c,
Buffer buffer 
)

Stores character to the buffer->buffr_char

Parameters
ccharacter to be stored in the buffer->buffr_char
bufferstruct where character will be stored
85{
86 buffer->buffr_char = *c; // Character initializes inside buffer->buffr_char
87 buffer->buf_size = 1; // Sets bufsize to one as new character is stored in buffr_char
88}