运用自己设置的输出函数来实现简单的printf功能
实现输出字符串
#include <stdio.h>
int my_printf( const char *frm, ...) //c++中若没有const会报错
{
int cnt = 0;
for(int i= 0;frm[i]; i++) //frm[i]可以判断字符串是否到了末尾,到末尾停止【详解见下】
{
putchar(frm[i]);
++cnt;
}
return cnt; //printf的返回值是返回向屏幕输出值的个数(看下面的连接)此处设置与其功能保持一致【详解见下】
}
int main()
{
printf("hello world\n"); // (1)
my_printf("hello world\n");
int a = 123;
printf("int (a) = %d\n", a); //(2)
my_printf("int (a) = %d\n", a);
return 0;
}
frm[i]可以判断字符串是否到了末尾,到末尾停止。这是因为它作为一个判断条件,在已知每个字符(串)末尾都有一个看不到的【‘\0’】,它对应的值为0,0为假值,判断条件遇到它以后条件不成立就会结束
第一组printf 和 my_printf 打印输出的结果是一样的
第二组打印输出的结果是不一样的
实现输出字符串+数值
先了解一下变参函数——va族
1.0
#include <stdio.h>
#include <stdarg.h> //va一族所在的头文件
int my_printf( const char *frm, ...) //c++中若没有const会报错
{
int cnt = 0;
va_list arg;
va_start(arg, frm);
#define PUTC(a) putchar(a), ++cnt
for (int i = 0; frm[i]; i++) //frm[i]到末尾为止
{
switch (frm[i])
{
case '%':
{
switch (frm[++i])
{
case '%': PUTC(frm[i]); break;
case 'd':
{
int x = va_arg(arg, int);
int temp = 0;
while(x) //先翻转数值
{
temp = temp * 10 + x % 10;
x /= 10;
}
while(temp)
{
PUTC(temp % 10 + 48); //48等价于‘0’
temp /= 10;
}
} break;
}break;
} break;
default: PUTC(frm[i]); break;
}
}
#undef PUTC
return cnt;
}
int main()
{
int a = 123;
printf("int (a) = %d\n", a); //(2)
my_printf("int (a) = %d\n", a);
printf("int (a) = %d\n", 0); //(3)
my_printf("int (a) = %d\n", 0);
return 0;
}
此时我们发现,第二组可输出了,第三组又不行了
这一步的完善其实比较简单,将while改为do while即可
2.0
#include <stdio.h>
#include <stdarg.h>
int my_printf( const char *frm, ...)
{
int cnt = 0;
va_list arg;
va_start(arg, frm);
#define PUTC(a) putchar(a), ++cnt
for (int i = 0; frm[i]; i++)
{
switch (frm[i])
{
case '%':
{
switch (frm[++i])
{
case '%': PUTC(frm[i]); break;
case 'd':
{
int x = va_arg(arg, int);
int tenp = 0;
while(x)
{
temp = temp * 10 + x % 10;
x /= 10;
}
do //while改为do while
{
PUTC(temp % 10 + 48);
temp /= 10;
}while(temp);
} break;
}break;
} break;
default: PUTC(frm[i]); break;
}
}
#undef PUTC
return cnt;
}
int main()
{
int a = 123;
printf("int (a) = %d\n", a); //(3)
my_printf("int (a) = %d\n", a);
printf("int (a) = %d\n", 0); // (4)
my_printf("int (a) = %d\n", 0);
printf("int (a) = %d\n", 1000); // (5)
my_printf("int (a) = %d\n", 1000);
return 0;
}
没想到吧,第四组可以了,第五组又不行了
我受够了下面再改改
3.0
#include <stdio.h>
#include <stdarg.h>
int my_printf( const char *frm, ...)
{
int cnt = 0;
va_list arg;
va_start(arg, frm);
#define PUTC(a) putchar(a), ++cnt
for (int i = 0; frm[i]; i++)
{
switch (frm[i])
{
case '%':
{
switch (frm[++i])
{
case '%': PUTC(frm[i]); break;
case 'd':
{
int x = va_arg(arg, int);
if(x<0) PUTC('-'),x=-x; //实现负数也可以输出
int tenp = 0,digit=0;
do //while改为do while
{
temp = temp * 10 + x % 10;
x /= 10;
++digit;
}while(x)
while(digit--) //这里也改
{
PUTC(temp % 10 + 48);
temp /= 10;
}
} break;
}break;
} break;
default: PUTC(frm[i]); break;
}
}
#undef PUTC
return cnt;
}
int main()
{
int a = 123;
printf("int (a) = %d\n", a); //(3)
my_printf("int (a) = %d\n", a);
printf("int (a) = %d\n", 0); // (4)
my_printf("int (a) = %d\n", 0);
printf("int (a) = %d\n", 1000); // (5)
my_printf("int (a) = %d\n", 1000);
printf("int (a) = %d\n", -123); // (6)
my_printf("int (a) = %d\n", -123);
return 0;
}
4.0
再有不完善的地方自己改去吧,我受不了了,呜呜,就酱了
#include <stdio.h>
#include <stdarg.h>
#include <inttypes.h>
int rev_num(int n, int *temp)
{
int digit = 0;
*temp = 0;
do
{
*temp = *temp * 10 + n % 10;
n /= 10;
++digit;
} while (n);
return digit;
}
int output_num(int n, int digit)
{
int cnt = 0;
while (digit--)
{
putchar(n % 10 + 48), ++cnt;
n /= 10;
}
return cnt;
}
int my_printf(const char *frm, ...)
{
int cnt = 0;
va_list arg;
va_start(arg, frm);
#define PUTC(a) putchar(a), ++cnt
for (int i = 0; frm[i]; i++)
{
switch (frm[i])
{
case '%':
{
switch (frm[++i])
{
case '%': PUTC(frm[i]); break;
case 'd':
{
int x = va_arg(arg, int);
uint32_t x;
if (xx < 0) PUTC('-'), x = -x;
else x = x;
int temp1, temp2;
int x1 = x / 100000, x2 = x % 100000;
int digit1 = rev_num(x1, &temp1);
int digit2 = rev_num(x2, &temp2);
if (x1) digit2 = 5;
else digit1 = 0;
cnt += output_num(temp1, digit1);
cnt += output_num(temp2, digit2);
} break;
case 's':
{
const char *str = va_arg(arg, const char *);
for (int i = 0; str[i]; i++)
{
PUTC(str[i]);
}
} break;
}
} break;
default: PUTC(frm[i]); break;
}
}
#undef PUTC
va_end(arg);
return cnt;
}
int main()
{
int n;
while (~scanf("%d", &n))
{
printf(" has %d digits!\n", printf("%d", n));
my_printf(" has %d digits!\n", my_printf("%d", n));
}
printf("int (a) = %d\n", -123);
my_printf("int (a) = %d\n", -123);
printf("INT32_MAX = %d\n", INT32_MAX);
my_printf("INT32_MAX = %d\n", INT32_MAX);
printf("INT32_MIN = %d\n", INT32_MIN);
my_printf("INT32_MIN = %d\n", INT32_MIN);
char str[100] = "I love China";
printf("%s\n", str);
my_printf("%s\n", str);
return 0;
}