Algorithms_in_C 1.0.0
Set of algorithms implemented in C.
Loading...
Searching...
No Matches
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
 
#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.
 
char get_ch (char *p, Buffer *buffer)
 Returns specific required next character.
 
void unget_ch (char *c, Buffer *buffer)
 Stores character to the buffer->buffr_char
 
int get_number_of_digits (int n)
 Calculates the number of digits in a number.
 
void put_char (char s)
 Prints one character on screen.
 
void reverse_str (char *p)
 Reverses a string using two pointer algorithm
 
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.
 
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.
 
void min_printf (char *fmt,...)
 min_printf is the function same as printf
 

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:

Macro Definition Documentation

◆ INT_MAX_LENGTH

#define INT_MAX_LENGTH   10

for malloc and free functions

for write function for va_start and va_arg functions

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

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

◆ 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
101{
102 int digits = 0; // Stores encountered number of digits
103 while (n > 0) {
104 ++digits; // Since number still contains a digit, so increment digit variable
105 n /= 10; // Removes last digit from number
106 }
107 return digits;
108}

◆ 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)
276{
277 /* Skip % if p is pointing to it.*/
278 if (*p == '%')
279 ++p;
280
281 /* Calculates the width specified. */
282 while (*p != '.' && is_number(p))
283 *width = *width * 10 + (*p++ - '0');
284
285 /* Calculates the precision specified.*/
286 if (*p == '.' /* Since a precision is always specified after a '.'. */) {
287 while (is_number(++p))
288 *precision = *precision * 10 + (*p - '0');
289 unget_ch(p, buffer); // The non number will be stored in `buffer->buffr`
290 }
291 return p;
292}
void unget_ch(char *c, Buffer *buffer)
Stores character to the buffer->buffr_char
Definition min_printf.h:88
int is_number(char *c)
Checks if a character is a number.
Definition min_printf.h:62
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
63{
64 return (*c >= '0' && *c <= '9') ? 1 : 0;
65}

◆ 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
300{
301 va_list ap; // Points to each unnamed arg in turn
302 char *p, *sval; // p will be used to point to fmt and sval will store string value
303 char cval; // Stores character value
304 int ival; // For integer values
305 double dval; // For double or float values
306 va_start(ap, fmt); // Makes ap points to first unnames argument
307
308 /* Initializing the buffer for storing character. */
309 Buffer *buffer = (Buffer *) malloc(sizeof(Buffer));
310 buffer->buf_size = 0; // Initially set buffer size to zero as no character is inserted
311
312 for (p = fmt; *p != '\0'; ++p) {
313
314 /* If p != '%' then the character is printed to screen. */
315 if (*p != '%') {
316 put_char(*p);
317 continue;
318 }
319
320 int width = 0; // Stores width specified
321 int precision = 0; // Stores precision specified
322
323 /* Updates values of width, precision and p. */
324 p = get_width_and_precision(p, buffer, &width, &precision);
325
326 /* Checks format of next argument.*/
327 switch (get_ch(p, buffer)) {
328 case 'd': // Integer
329 ival = va_arg(ap, int);
330 print_int_value(ival, width, precision);
331 break;
332 case 'c': // Character
333 cval = va_arg(ap, int);
334 put_char(cval);
335 break;
336 case 'f': // Float or Double
337 dval = va_arg(ap, double);
338
339 // If precision is not specified then default value is applied
340 if (precision == 0)
341 precision = PRECISION_FOR_FLOAT;
342 print_double_value(dval, width, precision);
343 break;
344 case 's': // String pointer
345 sval = va_arg(ap, char *);
346 print_string(sval, width, precision);
347 break;
348 default:
349 put_char(*p);
350 break;
351 }
352 }
353 va_end(ap);
354}
#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:158
char get_ch(char *p, Buffer *buffer)
Returns specific required next character.
Definition min_printf.h:74
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:210
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:275
void put_char(char s)
Prints one character on screen.
Definition min_printf.h:114
void print_string(char *p, int width, int precision)
Definition min_printf.h:238
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

49{
50 int n = 1; ///< This number will be returned as ten to power of a
51 for (int i = 1; i <= a; ++i)
52 n *= 10 ;
53 return n;
54}

◆ 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)
211{
212 int ndigits = get_number_of_digits((int) dval); // Store number of digits before decimal in dval
213 int reqd_blanks = width - (precision + 1) - ndigits; // Blanks to be printed before printing dval, just to cover the width
214
215 print_int_value((int) dval, reqd_blanks, 0); // Prints the part before decimal
216
217 put_char('.'); // Print decimal
218
219 /*Deletes digits before decimal and makes them zero. For example:
220 if dval = 1923.79022, them this will make dval = 0.79022
221 */
222 dval = dval - (int) dval;
223
224 dval *= power_of_ten(precision); // Brings precision number of digits after decimal to before decimal
225
226 print_int_value((int) dval, 0, precision); // Prints the remaining number
227}
int power_of_ten(int a)
Definition min_printf.h:48
int get_number_of_digits(int n)
Calculates the number of digits in a number.
Definition min_printf.h:100
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)

159{
160 char *p = (char *) malloc(INT_MAX_LENGTH * sizeof(char) + 1); /* +1 for '\0' */
161 char *s = p; // Temporary pointer
162 int size = 0; //!< Used to store number of digits in number
163
164 while (n > 0) {
165 *s++ = n % 10 + '0'; // Converts last digit of number to character and store it in p
166 ++size; // Increment size variable as one more digit is occurred
167 n /= 10; // Removes the last digit from the number n as we have successfully stored it in p
168 }
169 *s = '\0';
170
171 s = p; // Again point back s to starting of p
172
173 reverse_str(p);
174
175 /*!
176 * The next two conditions check weather it is required to
177 * add blanks before printing the number (ie: width)and is it specified how many
178 * zeros to be printed before the number is printed (ie: precision)
179 */
180 if (width > 0 && size < width)
181 for (int i = 0; i < (width - precision); ++i)
182 put_char(' ');
183
184 if (precision > 0 && precision > size)
185 for (int i = 0; i < (precision - size); ++i)
186 put_char('0');
187
188 /* Prints the number.*/
189 while (*s != '\0')
190 put_char(*s++);
191
192 free(p);
193}
#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:128
#define INT_MAX_LENGTH
for malloc and free functions
Definition min_printf.h:29
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)
239{
240 int size = 0; // Stores number of character in string
241 char *s = p; // Temporary pointer
242
243 /* Calculates size of string p*/
244 while (*s != '\0') {
245 ++size;
246 ++s;
247 }
248
249 s = p; // Point s to starting of p
250
251 /* Checks how many characters to be printed.
252 if precision is defined then size variable is changed to precision so that only precision
253 number of characters were printed.
254 */
255 if (precision != 0 && precision < size)
256 size = precision;
257
258 /* Prints blanks to cover the width if required*/
259 for (int i = 0; i < (width - size); ++i)
260 put_char(' ');
261
262 /* Print the string.*/
263 for (int i = 0; i < size; ++i)
264 put_char(*s++);
265
266}
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
115{
116 /* buf used for storing character to be printed in an array (+1 for '\0')*/
117 char *buf = (char *) malloc(sizeof(char) + 1);
118 *buf = s;
119 *(buf + 1) = '\0';
120 write(1, buf, 1);
121 free(buf);
122}

◆ reverse_str()

void reverse_str ( char *  p)

Reverses a string using two pointer algorithm

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

◆ 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
89{
90 buffer->buffr_char = *c; // Character initializes inside buffer->buffr_char
91 buffer->buf_size = 1; // Sets bufsize to one as new character is stored in buffr_char
92}