一)实现自己的printf
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
// printf with format
void my_printf(char *fmt, ...)
{
va_list ap; //char *
int d;
char c, *s;
va_start(ap, fmt); // 让ap指向 fmt 后面的字符串(即 第二个参数要是 函数参数 ... 前面的那个)
while (*fmt)
{
switch (*fmt)
{
case 's': /* string */
s = va_arg(ap, char *); // 然后返回这个指定类型的值首地址给 s,并把ap的位置往后移动指定类型长度
printf("catch a string:%s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("catch a int:%d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("catch a char: %c\n", c);
break;
default:
if(*fmt == ' ')
printf(" -> unprocessed character: space \n");
else
printf(" -> unprocessed character: %c\n", *fmt);
break;
}
fmt++;
}
va_end(ap); // ap指针置空
}
// printf without format
int my_printf_string( char *str, ... )
{
va_list argp;
int argno = 0;
char* para;
argno++;
printf("str[%d]: %s\n", argno, str);
va_start( argp, str );
while (1)
{
para = va_arg( argp, char* );
if ( strcmp(para, "") == 0 )
{
break;
}
else
{
argno++;
printf("str[%d]: %s\n", argno, para);
}
}
va_end( argp );
return 0;
}
int main(int argc, char** argv)
{
my_printf_string("123","abc","o3o","last one", "");
my_printf(" %s %d %c ", "test string", 100, 'c');
return 0;
}
二)彩色输出格式:
\033[显示方式;前景色;背景色m输出字符串\033[0m
或
\e[显示方式;前景色;背景色m输出字符串\033[0m
显示方式:0(默认)、1(粗体/高亮)、22(非粗体)、4(单条下划线)、24(无下划线)、5(闪烁)、25(无闪烁)、7(反显、翻转前景色和背景色)、27(无反显)
前景色 背景色:0(黑)、1(红)、2(绿)、 3(黄)、4(蓝)、5(洋红)、6(青)、7(白)
字体颜色(前景色): 30+颜色index
背景颜色(背景色): 40+颜色index
例子:
#define NONE "\e[0;0;0m"
//颜色
#define NONE "\e[0;0;0m"
#define BLACK "\e[0;30m"
#define L_BLACK "\e[1;30m"
#define RED "\e[0;31m"
#define L_RED "\e[1;31m"
#define GREEN "\e[0;32m"
#define L_GREEN "\e[1;32m"
#define BROWN "\e[0;33m"
#define YELLOW "\e[1;33m"
#define BLUE "\e[0;34m"
#define L_BLUE "\e[1;34m"
#define PURPLE "\e[0;35m"
#define L_PURPLE "\e[1;35m"
#define CYAN "\e[0;36m"
#define L_CYAN "\e[1;36m"
#define GRAY "\e[0;37m"
#define WHITE "\e[1;37m"
//样式
#define BOLD "\e[1m"
#define UNDERLINE "\e[4m"
#define BLINK "\e[5m"
#define REVERSE "\e[7m"
#define HIDE "\e[8m"
#define CLEAR "\e[2J"
#define CLRLINE "\r\e[K"
#define BOLD_RED_GREEN "\e[1;31;46m" //粗体高亮 + 红字 + 绿底
printf("[%2u]" BOLD_RED_GREEN "BLACK " NONE L_BLACK "L_BLACK\n" NONE, __LINE__);
printf("[%2u]" RED "RED " L_RED "L_RED\n" NONE, __LINE__);
printf("[%2u]" GREEN "GREEN " L_GREEN "L_GREEN\n" NONE, __LINE__);
printf("[%2u]" BROWN "BROWN " YELLOW "YELLOW\n" NONE, __LINE__);
printf("[%2u]" BLUE "BLUE " L_BLUE "L_BLUE\n" NONE, __LINE__);
printf("[%2u]" PURPLE "PURPLE " L_PURPLE "L_PURPLE\n" NONE, __LINE__);
printf("[%2u]" CYAN "CYAN " L_CYAN "L_CYAN\n" NONE, __LINE__);
printf("[%2u]" GRAY "GRAY " WHITE "WHITE\n" NONE, __LINE__);
printf("[%2u]" BOLD "GRAY " PURPLE "WHITE\n" NONE, __LINE__);
关于终端输出设置:SecureCRT -> Options -> Session Option
实际效果:
三)带有输出等级的打印
#define PRINT_OPEN 1
#ifdef PRINT_OPEN
#define PRINT_LEVEL 4
#define L1 1 //fatal
#define L2 2 //alarm
#define L3 3 //error
#define L4 4 //warm
#define L5 5 //info
#define L6 6 //debug
//my_printk:可用的打印输出函数
#define PRINT_INFO(level, fmt, args...) do{\
if(PRINT_LEVEL >= level)\
{\
if(L3 >= level)\
{\
my_printk("\e[1;31m %s(%d): \e[1;0;0m", __FUNCTION__, __LINE__);\
}\
else\
{\
my_printk("%s(%d):", __FUNCTION__, __LINE__);\
}\
my_printk(fmt, args);\
}\
}while(0);\
#else
#define PRINT_INFO(level, fmt, args...) do{}while(0);
#endif
使用例子:
PRINT_INFO(L2, "data = %d \n", data);
四)