how do i go about writing my own printf function, so that i do not have to include
stdio.h
Printable View
how do i go about writing my own printf function, so that i do not have to include
stdio.h
Why do you want to re-write printf? For funny?
All you need to do is fopen() stdout and once you have the string the way you want it, you write it to that file.
>how do i go about writing my own printf function
You first learn how to write a function that takes a variable number of arguments, then you learn how to convert various supported types into strings and write those strings using a lower level function, putchar as one possible option. Then you learn how to process the formatting flags so that your printf will handle more complex formatting than just type conversion. Here's a quick and dirty example, it can be made to be more compact and elegant with a little effort:
Also note that this only implements the %d flag, and even then it's not fully functional. ;)Code:#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
void fprint(const char *format, ...);
int
main(void)
{
fprint("|%12d|\n", 45);
fprint("|%012d|\n", 45);
fprint("|% 012d|\n", 45);
fprint("|%+12d|\n", 45);
fprint("|%+012d|\n", 45);
fprint("|%-12d|\n", 45);
fprint("|%- 12d|\n", 45);
fprint("|%-+12d|\n", 45);
fprint("|%12.4d|\n", 45);
fprint("|%-12.4d|\n\n", 45);
fprint("|%12d|\n", -45);
fprint("|%012d|\n", -45);
fprint("|% 012d|\n", -45);
fprint("|%+12d|\n", -45);
fprint("|%+012d|\n", -45);
fprint("|%-12d|\n", -45);
fprint("|%- 12d|\n", -45);
fprint("|%-+12d|\n", -45);
fprint("|%12.4d|\n", -45);
fprint("|%-12.4d|\n", -45);
return 0;
}
static int
length(
int value
)
{
int n = 0;
if (value == 0) {
return 1;
}
while (value) {
++n;
value /= 10;
}
return n;
}
static void
r_write_value(
int value,
int n
)
{
/* Assume positive value */
if (n) {
r_write_value(value / 10, n - 1);
if (value) {
putchar(value % 10 + '0');
}
else {
putchar('0');
}
}
}
static void
write_value(
int value,
int n
)
{
if (value == 0) {
putchar('0');
}
else {
r_write_value(value, n);
}
}
void
fprint(
const char *format,
...
)
{
va_list args;
const char *it;
int value;
int i;
va_start(args, format);
for (it = format; *it; it++) {
if (*it == '%') {
int left = 0; /* Left justify */
int plus = 0; /* Print sign */
int zero = 0; /* Zero padding */
int space = 0; /* Whitespace sign replacement */
int field_width = 0; /* Precision before decimal */
int precision = 0; /* Precision after decimal */
while (*(++it) != 'd') {
/* Specific flags */
switch (*it) {
case ' ': space = 1; break;
case '+': plus = 1; break;
case '0': zero = 1; break;
case '-': left = 1; break;
}
/* Precision */
if (isdigit(*it)) {
char *save;
field_width = (int)strtol(it, &save, 10);
it = save;
if (*it == '.') {
precision = (int)strtol(it + 1, &save, 10);
}
it = save;
break;
}
}
value = va_arg(args, int);
/* Print formatting */
if (!precision) {
precision = length(value);
}
field_width -= precision;
if (space || plus || value < 0) {
--field_width;
}
if (!left) {
if (value < 0) {
if (!zero) {
for (i = 0; i < field_width; i++) {
putchar(' ');
}
putchar('-');
}
else {
putchar('-');
for (i = 0; i < field_width; i++) {
putchar('0');
}
}
}
else {
if (space) {
putchar(' ');
}
if (!zero) {
for (i = 0; i < field_width; i++) {
putchar(' ');
}
if (plus) {
putchar('+');
}
}
else {
if (plus) {
putchar('+');
}
for (i = 0; i < field_width; i++) {
putchar('0');
}
}
}
write_value(abs(value), precision);
}
else {
if (value < 0) {
putchar('-');
}
else {
if (plus) {
putchar('+');
}
else if (space) {
putchar(' ');
}
}
write_value(abs(value), precision);
for (i = 0; i < field_width; i++) {
putchar(' ');
}
}
}
else {
putchar(*it);
}
}
va_end(args);
}
>so that i do not have to include stdio.h
That's not really a good reason to write your own printf. If you really don't want to include stdio.h you can declare a prototype for printf:
In the end, providing declarations is all stdio.h does for you. If you provide your own (correct!) prototype then the effect is the same. :)Code:int printf(const char *format, ...);
int
main(void)
{
printf("Hello, world!\n");
return 0;
}