C语言 printf

本文详细介绍如何在C语言中自定义printf函数,包括格式化输出和非格式化输出的实现。此外,还介绍了如何使用ANSI转义序列进行彩色输出,以及如何设置输出等级,适用于需要控制台美观和信息级别的应用程序开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一)实现自己的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);

 


四)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值