51

编程这么久, printf 知多少(二)

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzUxMTk4MzY3MA%3D%3D&%3Bmid=2247484642&%3Bidx=1&%3Bsn=e613416a9a5e9fd0b4be6888d3c16a13
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,麻烦点个在看或点个赞,感谢~          文章首发   公众号—— Pou光明

接着上篇文章,把剩下的参数理一理。

一、设置printf输出字体颜色

格式:

printf( \033[ 字体背景颜色 ; 字体颜色 m 字符串 \033[0m );

把\033换成 \e 是一样的,为了使程序更有可读性,可以定义为宏

字背景颜色范围: 40--49 字颜色 : 30--39

40: 黑 30:

41: 红 31:

42: 绿 32: 绿

43: 黄 33:

44: 蓝 34:

45: 紫 35:

46: 深绿 36: 深绿

47: 白色 37: 白色

例子:

    char cTest[] = "hello";


printf("\033[45;36m[hello world]\n\033[0m");
printf("\033[32m[hello world]\n\033[0m");
printf("\033[32m[%s]\n\033[0m",cTest);

运行结果:

YF7BBbZ.png!mobile

其他属性汇总:

\033[0m 关闭所有属性

\033[1m 设置高亮度

\03[4m 下划线

\033[5m 闪烁

\033[7m 反显

\033[8m 消隐

\033[30m -- \033[37m 设置前景色

\033[40m -- \033[47m 设置背景色

\033[nA 光标上移 n

\03[nB 光标下移 n

\033[nC 光标右移 n

\033[nD 光标左移 n

\033[y;xH 设置光标位置

\033[2J 清屏

\033[K 清除从光标到行尾的内容

\033[s 保存光标位置

\033[u 恢复光标位置

\033[?25l 隐藏光标

\33[?25h 显示光标

二、# ## 运算符

1、 # 预编译时将参数转换为字符串

即加上 ””

示例:

#define CONVERT(TEST) printf("%s:%d\n", #TEST, TEST);


int main()
{
int test1 = 1, test2 = 2;


CONVERT(test1);
CONVERT(test2);
CONVERT(test1 + test2);


return 0;
}

程序结果:

dh@ubuntu:~/workSpace/Linux/printf$ gcc printf.c 
dh@ubuntu:~/workSpace/Linux/printf$ ./a.out
test1:1
test2:2
test1 + test2:3

2、 ## 连接运算符

预编译时拼接两个符号。

示例:

#define SPLICE(PARAM1, PARAM2) (PARAM1##PARAM2)


int num = SPLICE(12, 34);
printf("num = %d \n", num);


int num1 = SPLICE(,34);
printf("num = %d \n", num1);

程序结果:

num = 1234 
num = 34

如果连接两个字符串,会有下面的错误。

gcc 编译器会遇到的 error does not give a valid preprocessing token

VC编译器不会有问题

感兴趣的朋友可以深入了解一下,这是不同编译器对同一问题产生的看法不同导致的。

三、__VA_ARGS__ 可变参数的宏(C99)

只有gcc编译器支持。

宏参数列表最后一个参数为省略号(三个点 )

直接用例子感受下吧,就像做数学题一样。。。

#define MYPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
#define MYNEWPRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)


int i = 0;
int j = 1;
MYPRINTF("i=%d,j=%d\n",i,j); // 正确打印


MYNEWPRINTF("new hello world \n") ; // 编译正确
MYNEWPRINTF("i=%d,j=%d\n",i,j); // 正确打印

程序结果:

i=0,j=1
new hello world
i=0,j=1

四、总结

本来想弄明白printf后面各参数的含义,结果 .....

最后,昨天的日志输出也可以写成下面的形式:

#define DEBUG(fmt, ...) printf("\033[31m[TEST: %s:%d:%s:%s] "#fmt"\033[0m\r\n", __func__, __LINE__, __DATE__, __TIME__, ##__VA_ARGS__)

之后本公众号将不时转载关于robocon(萝卜坑 ) 的相关文章及其他有意思的东西。

MZzeIjR.png!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK