番外: 再谈前文的println函数
(1). 直接来看函数本体
说实话,这还是我第一次以番外篇的形式发博客,这次我稍微改进了上一篇中我们写过的println函数,相较于之前的版本,这次支持了%.nf,%ld, %lld, %u, %lu, %llu, %lf这些格式的输出,因为改动其实不算是很大,因此就随便发一篇了:
int println(const char* format, ...)
{
const char* p = format;
va_list ptr;
va_start(ptr, format);
int state{ 0 };
int _sum{ 0 };
char kf[15] = "%.1";
char pt{ 2 };
// 0 for default char
// 1 for % just %
// 2 for .(.kf)
// 3 for l(lf, ld, lu)
// 4 for ll(lld, llu, llf=lf)
// 5 for k(.kf)
for (; *p; p++) {
switch (*p) {
case '%':
if (state) {
state = 0, putchar(*p);
}
else state = 1;
break;
case 'l':
if (state) {
if (state == 1) state = 3;
else if (state == 3) state = 4;
else if (state == 4) {
return -1;
}
}
else putchar(*p), state = 0;
break;
case '.':
if (state == 1) {
state = 2;
}
else putchar(*p), state = 0;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (state) {
if (state == 2) {
state = 5;
}
kf[pt++] = *p;
}
else putchar(*p), state = 0;
break;
case 'd':
if (state) {
switch (state) {
case 1:
fprintf(stdout, "%d", va_arg(ptr, int));
break;
case 3:
fprintf(stdout, "%ld", va_arg(ptr, long));
break;
case 4:
fprintf(stdout, "%lld", va_arg(ptr, long long));
break;
}
_sum++, state = 0;
}
else putchar(*p), state = 0;
break;
case 'u':
if (state) {
switch (state) {
case 1:
fprintf(stdout, "%u", va_arg(ptr, unsigned int));
break;
case 3:
fprintf(stdout, "%lu", va_arg(ptr, unsigned long));
break;
case 4:
fprintf(stdout, "%llu", va_arg(ptr, unsigned long long));
break;
}
_sum++, state = 0;
}
else putchar(*p), state = 0;
break;
case 'c':
if (state == 1) {
putchar(va_arg(ptr, char));
_sum++, state = 0;
}
else putchar(*p), state = 0;
break;
case 'f':
if (state) {
switch (state) {
case 1:
fprintf(stdout, "%f", va_arg(ptr, float));
break;
case 3:
fprintf(stdout, "%lf", va_arg(ptr, double));
break;
case 4:
fprintf(stdout, "%lf", va_arg(ptr, double));
break;
case 2: case 5:
kf[pt++] = 'f';
kf[pt] = 0;
fprintf(stdout, kf, va_arg(ptr, double));
break;
}
_sum++, state = 0;
}
else putchar(*p), state = 0;
break;
case 's':
if (state == 1) {
const char* str = va_arg(ptr, const char*);
while (*str) {
putchar(*str++);
}
_sum++, state = 0;
}
else putchar(*p), state = 0;
break;
default:
putchar(*p);
if (state) state = 0;
}
}
putchar('\n');
va_end(ptr);
return _sum;
}
行数还是相对比较多的,不过因为算是相对简单的实现,看懂它应该不算很困难,不过如果大家有更好的实现方法,可以在评论区分享一下;同样,如果发现我写的这个部分有些什么bug,也可以直接提出,这对我会有很大帮助。