系列导航:上一篇:Print.h 开发记(一)V1.0
V1.2 是第一个”补课”版本:修掉 V1.0 遗留的 bug,同时一口气加入了好几个打印能力。
本版更新
- 修复 V1.0 遗留的 bug
- 加入
unsigned long long 的打印格式
- 加入打印数组功能,可以自选数组中每两个元素的打印格式
- 加入不支持的格式错误处理
- 加入颜色打印代码
无符号长长整型
1
| void print_ulonglong(unsigned long long num) { printf("%llu", num); }
|
%llu 对应 64 位无符号整型,配合 _Generic 分发表新增一个分支即可。
数组打印
数组打印支持自定义元素之间的分隔方式,一共三种:空格隔开、换行隔开、或者”下标 + 值”逐行打印,由调用方传一个模式常量决定——打印 int 数组和打印字符串数组都能得到好看的结果:
1 2 3
| #define printArrTypeSpace 0 #define printArrTypeln 1 #define printArrTypeName 2
|
错误处理
传入不支持的格式时不再静默输出,而是给出错误提示,避免”看起来打印成功了其实什么都没打”的迷惑行为。
颜色打印
1 2 3 4 5
| #define NONE(str) str "\033[m" #define RED(str) "\033[0;32;31m"NONE(str) #define GREEN(str) "\033[0;32;32m"NONE(str) #define BLUE(str) "\033[0;32;34m"NONE(str) #define CYAN(str) "\033[0;36m"NONE(str)
|
原理是 ANSI 转义序列:\033[0;32;31m 把终端切换到红色前景,\033[m 复位。这让库的输出第一次有了”彩色”。
V1.2 完整代码
Print.h1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
#ifndef __Print_H__ #define __Print_H__
#include <stdio.h> #include <string.h>
#define print(obj) (_Generic((obj),\ char: print_char,\ short int: print_short,\ int: print_int,\ float: print_float,\ double: print_double,\ const char*: print_cstr,\ char *: print_str,\ unsigned long long: print_ulonglong,\ default: print_error\ )(obj))
#define println(obj) {print(obj); printf("\n");}
void print_char(char num) { printf("%c", num); }
void print_short(short int num) { printf("%hd", num); }
void print_int(int num) { printf("%d", num); }
void print_ulonglong(unsigned long long num) { printf("%llu", num); }
void print_float(float num) { printf("%f", num); }
void print_double(double num) { printf("%lf", num); }
void print_cstr(const char *str) { printf("%s", str); }
void print_str(char *str) { printf("%s", str); }
#define NONE(str) str "\033[m" #define RED(str) "\033[0;32;31m"NONE(str) #define LIGHT_RED(str) "\033[1;31m"NONE(str) #define GREEN(str) "\033[0;32;32m"NONE(str) #define LIGHT_GREEN(str) "\033[1;32m"NONE(str) #define BLUE(str) "\033[0;32;34m"NONE(str) #define LIGHT_BLUE(str) "\033[1;34m"NONE(str) #define DARY_GRAY(str) "\033[1;30m"NONE(str) #define CYAN(str) "\033[0;36m"NONE(str) #define LIGHT_CYAN(str) "\033[1;36m"NONE(str) #define PURPLE(str) "\033[0;35m"NONE(str) #define LIGHT_PURPLE(str) "\033[1;35m"NONE(str) #define YELLOW(str) "\033[0;33m"NONE(str) #define LIGHT_YELLOW(str) "\033[1;33m"NONE(str) #define LIGHT_GRAY(str) "\033[0;37m"NONE(str) #define WHITE(str) "\033[1;37m"NONE(str)
#define TestColor(str)\ {\ println(RED (str));\ println(LIGHT_RED (str));\ println(GREEN (str));\ println(LIGHT_GREEN (str));\ println(BLUE (str));\ println(LIGHT_BLUE (str));\ println(CYAN (str));\ println(LIGHT_CYAN (str));\ println(PURPLE (str));\ println(LIGHT_PURPLE(str));\ println(YELLOW (str));\ println(LIGHT_YELLOW(str));\ println(DARY_GRAY (str));\ println(LIGHT_GRAY (str));\ println(WHITE (str));\ } #define TestColur TestColor
void print_error(void *data) { println(RED( "print error!" )); println(RED( "don't have this type to print!" )); }
#define printArrTypeSpace 0 #define printArrTypeln 1 #define printArrTypeName 2
#define GET_ARR_LEN(arrobj) \ (_Generic((arrobj),\ char *: strlen((const char *)arrobj),\ default: (sizeof(arrobj) / sizeof(arrobj[0]))\ ))
#define printArr(ArrName, type) { \ for (int i = 0; i < GET_ARR_LEN(ArrName); i++) \ { \ if(type == printArrTypeName) \ { \ print(#ArrName); \ print("["); \ print(i); \ print("] = "); \ println(ArrName[i]); \ } \ else \ { \ print(ArrName[i]); \ if(type) print("\n"); \ else print(" "); \ } \ } \ }
#define printlnArr(ArrName, type) {printArr(ArrName, type); print("\n");}
#endif
|
测试程序 main.c(V1.2)
main.c1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include "Print.h"
int main() { int num1 = 1; short int num2 = 2; char num3 = '3'; float num4 = 4.0f; double num5 = 5.0; const char *str1 = "6"; char str2[] = "7"; print(num1); print(num2); print(num3); print(num4); print(num5); print(str1); print(str2); print("\n");
println(num1); println(num2); println(num3); println(num4); println(num5); println(str1); println(str2);
int num[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; char ccl[10] = "ccl";
println(GET_ARR_LEN(num)); printlnArr(num, printArrTypeSpace);
println(GET_ARR_LEN(ccl)); printlnArr(ccl, printArrTypeSpace);
println(GET_ARR_LEN("987654321"));
int *p = 0; print(p);
TestColor("ccl is a boy");
return 0; }
|
系列导航