基于宏的格式化输出[无需添加换行符/不同数值类型/支持数组]
一、源代码说明
本文介绍的是开发框架的格式化输出文件,通过添加该头文件,可以避免在输出时频繁做的无用功,比如添加换行符、格式中添加变量名称、写循环输出数组元素。
-
开发框架函数和类的声明文件是 \utils\io_utils.h。
#ifndef BASICC_IO_UTILS_IO_UTILS_H_ #define BASICC_IO_UTILS_IO_UTILS_H_ #include <stdio.h> #include <limits.h> void PrintBinary(unsigned int value); #define PRINT_METADATA #ifdef PRINT_METADATA # define PRINTLNF(format, ...) printf("("__FILE__":%d) %s: "format"\n", __LINE__, __FUNCTION__ , ##__VA_ARGS__) #else # define PRINTLNF(format, ...) printf(format"\n", ##__VA_ARGS__) #endif #define PRINT_CHAR(char_value) PRINTLNF(#char_value": %c", char_value) #define PRINT_WCHAR(char_value) PRINTLNF(#char_value": %lc", char_value) #define PRINT_INT(int_value) PRINTLNF(#int_value": %d", int_value) #define PRINT_LONG(long_value) PRINTLNF(#long_value": %ld", long_value) #define PRINT_LLONG(long_value) PRINTLNF(#long_value": %lld", long_value) #define PRINT_BINARY(int_value) PrintBinary((unsigned int) int_value); #define PRINT_HEX(int_value) PRINTLNF(#int_value": %#x", int_value) #define PRINT_BOOL(bool_value) PRINTLNF(#bool_value": %s", bool_value ? "true" : "false") #define PRINT_DOUBLE(double_value) PRINTLNF(#double_value": %g", double_value) #define PRINT_STRING(string_value) PRINTLNF(#string_value": %s", string_value) #define PRINT_ARRAY(format, array, length) \ { int array_index; \ for (array_index = 0; array_index < length; ++array_index) { \ printf(format, array[array_index]); \ };\ printf("\n"); } #define PRINT_INT_ARRAY_LN(array, length) \ { int i; \ for (i = 0; i < length; ++i) { \ PRINTLNF(#array"[%d]: %d", i, array[i]); \ }} #define PRINT_INT_ARRAY(array, length) PRINT_ARRAY("%d, ", array, length) #define PRINT_CHAR_ARRAY(array, length) PRINT_ARRAY("%c, ", array, length) #define PRINT_DOUBLE_ARRAY(array, length) PRINT_ARRAY("%g, ", array, length) #endif //BASICC_IO_UTILS_IO_UTILS_H_
二、格式化输出
1. 添加换行符
自动添加换行符,并添加文件、行号和函数名等信息
说明
#define PRINT_METADATA
#ifdef PRINT_METADATA
# define PRINTLNF(format, ...) printf("("__FILE__":%d) %s: "format"\n", __LINE__, __FUNCTION__ , ##__VA_ARGS__)
#else
# define PRINTLNF(format, ...) printf(format"\n", ##__VA_ARGS__)
#endif
- 条件编译 :若定义
PRINT_METADATA
,则添加文件名(FILE)、行号(LINE)和函数名(FUNCTION)等信息;若无,则直接添加换行符; PRINTLNF(format, ...)
:“...”代表传入变长参数_VA__ARG__;##__VA_ARGS__
: __VA_ARGS__前的##号是为了避免未传入参数时报错,由编译器处理此情况;
示例
/*
* 程序名:demo_PRINTLNF.c,此程序演示框架中 PRINTLNF 函数的使用。
*/
#include "io_utils.h"
int main(void){
int x = 5;
PRINTLNF("x=%d",x); //无需添加换行符,自动换行
PRINTLNF("NoValueInput"); //支持无参数输入,自动换行
}
//结果输出
(\demo_PRINTLNF.c:10) main: x:5
(\demo_PRINTLNF.c:11) main: NoValueInput
2. 格式化输出数值
支持格式化输出字符、宽字符、整型、长整型、二进制、十六进制、双浮点型、字符串数据
说明
#define PRINT_CHAR(char_value) PRINTLNF(#char_value": %c", char_value)
#define PRINT_WCHAR(char_value) PRINTLNF(#char_value": %lc", char_value)
#define PRINT_INT(int_value) PRINTLNF(#int_value": %d", int_value)
#define PRINT_LONG(long_value) PRINTLNF(#long_value": %ld", long_value)
#define PRINT_LLONG(long_value) PRINTLNF(#long_value": %lld", long_value)
#define PRINT_BINARY(int_value) PrintBinary((unsigned int) int_value);
#define PRINT_HEX(int_value) PRINTLNF(#int_value": %#x", int_value)
#define PRINT_BOOL(bool_value) PRINTLNF(#bool_value": %s", bool_value ? "true" : "false")
#define PRINT_DOUBLE(double_value) PRINTLNF(#double_value": %g", double_value)
#define PRINT_STRING(string_value) PRINTLNF(#string_value": %s", string_value)
PRINTLNF(#char_value": %c", char_value)
: #char_value 转化变量名未字符串;
示例
/*
* 程序名:demo_PRINT_XXX.c,此程序演示框架中数值格式化输出函数的使用。
*/
#include "io_utils.h"
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <wchar.h>
int main(void){
char char_value = 'A';
wchar_t wchar_value = 'a';
int int_value = 6; // -2147483648 到 2147483647
long int long_value = 2147483647; //
bool bool_value = 1;
double double_value = 3.24;
char string_value[] ="hello world!";
PRINT_INT(sizeof(wchar_t));
PRINT_INT(sizeof(int));
PRINT_LONG(sizeof(long int));
PRINT_LONG(sizeof(long long int));
PRINT_LONG(sizeof(float));
PRINT_LONG(sizeof(double));
PRINT_CHAR(char_value);
PRINT_WCHAR(wchar_value);
PRINT_INT(int_value);
PRINT_LONG(long_value);
PRINT_LLONG(long_value);
PRINT_HEX(int_value);
PRINT_BOOL(bool_value);
PRINT_DOUBLE(double_value);
PRINT_STRING(string_value);
}
//结果输出
(\demo_PRINT_XXX.c:20) main: sizeof(wchar_t): 2
(\demo_PRINT_XXX.c:21) main: sizeof(int): 4
(\demo_PRINT_XXX.c:22) main: sizeof(long int): 4
(\demo_PRINT_XXX.c:23) main: sizeof(long long int): 8
(\demo_PRINT_XXX.c:24) main: sizeof(float): 4
(\demo_PRINT_XXX.c:25) main: sizeof(double): 8
(\demo_PRINT_XXX.c:27) main: char_value: A
(\demo_PRINT_XXX.c:28) main: wchar_value: a
(\demo_PRINT_XXX.c:29) main: int_value1: 6
(\demo_PRINT_XXX.c:30) main: long_value: 2147483647
(\demo_PRINT_XXX.c:31) main: long_value: 2147483647
(\demo_PRINT_XXX.c:33) main: int_value2: 0xf
(\demo_PRINT_XXX.c:34) main: bool_value: true
(\demo_PRINT_XXX.c:35) main: double_value: 3.24
(\demo_PRINT_XXX.c:36) main: string_value: hello world!
宽字符与Unicode_C语言中文网 (biancheng.net)
(4条消息) C语言的数据类型及用%u输出char的问题_Little_Fall的博客-CSDN博客_c语言打印char类型
(4条消息) C 数据类型(bit,byte,word;char,int,long;float,double)_deepwater_zone的博客-CSDN博客_数据类型bit
3. 格式化输出数组
逐个输出不同数据类型数组元素
说明
#define PRINT_ARRAY(format, array, length) \
{ int array_index; \
for (array_index = 0; array_index < (length); ++array_index) { \
printf(format, (array)[array_index]); \
};\
printf("\n"); }
#define PRINT_INT_ARRAY_LN(array, length) \
{ int i; \
for (i = 0; i < (length); ++i) { \
PRINTLNF(#array"[%d]: %d", i, (array)[i]); \
}}
#define PRINT_HEX_ARRAY_LN(array, length) \
{ int array_index; \
for (array_index = 0; array_index < (length); ++array_index){ \
PRINTLNF(#array"[%d]: %#x", array_index, (array)[array_index]); \
}}
#define PRINT_INT_ARRAY(array, length) PRINT_ARRAY("%d, ", array, length)
#define PRINT_CHAR_ARRAY(array, length) PRINT_ARRAY("%c, ", array, length)
#define PRINT_DOUBLE_ARRAY(array, length) PRINT_ARRAY("%g, ", array, length)
PRINT_ARRAY
需输入打印格式PRINT_INT_ARRAY_LN
逐个输出数组(整型数据)元素换行PRINT_HEX_ARRAY_LN
逐个输出数组(十六进制数据)元素换行PRINT_INT_ARRAY
、PRINT_CHAR_ARRAY
、PRINT_DOUBLE_ARRAY
逐个输出数组元素,不换行
示例
/*
* 程序名:demo_PRINT_ARRAY.c,此程序演示框架中 PRINT_ARRAY、PRINT_INT_ARRAY、PRINT_CHAR_ARRAY、PRINT_DOUBLE_ARRAY宏定义的使用。
*/
#include <stdio.h>
#include "io_utils.h"
#define ARRAY_SIZE 10
int global_array[ARRAY_SIZE]; //全局数组,未初始化,存于静态数据区
int main(void){
char array_char[ARRAY_SIZE] = {[2] = 'o', 'l', 'l'}; //字符串数组,指定位置初始化
int array_int_uninit[ARRAY_SIZE]; //局部数据,未初始化,存于函数堆栈
int array_int_init[ARRAY_SIZE] = {1,2,3}; //局部初始化
double array_double[ARRAY_SIZE] = {[3]=4.1,3.4,3.5};//指定位置初始化
PRINT_CHAR_ARRAY(array_char,ARRAY_SIZE);
PRINT_INT_ARRAY(global_array,ARRAY_SIZE);
PRINT_INT_ARRAY(array_int_init,ARRAY_SIZE);
PRINT_INT_ARRAY(array_int_uninit,ARRAY_SIZE);
PRINT_HEX_ARRAY_LN(array_int_uninit,ARRAY_SIZE);
PRINT_INT_ARRAY_LN(array_int_init,ARRAY_SIZE);
PRINT_DOUBLE_ARRAY(array_double,ARRAY_SIZE);
return 0;
}