基于宏的格式化输出[无需添加换行符/不同数值类型/支持数组]

一、源代码说明

本文介绍的是开发框架的格式化输出文件,通过添加该头文件,可以避免在输出时频繁做的无用功,比如添加换行符、格式中添加变量名称、写循环输出数组元素。

  • 开发框架函数和类的声明文件是 \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

C 数据类型 | 菜鸟教程 (runoob.com)

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_ARRAYPRINT_CHAR_ARRAYPRINT_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;
}
posted @ 2022-04-04 19:26  Oddpage  阅读(165)  评论(0编辑  收藏  举报