【C语言】printf表格显示,C语言表格,C语言显示框架

演示效果

演示

功能讲解

1. 简绍

简单显示表格信息,可以自定义边框。

2. 使用

	//定义表格句柄
	TABLE_HANDLE handle;
    TABLE_COL tableCol;

    tableCol.count = 2;//初始化每一行表格有几列
    int width[] = { 6, 8 };//每一列的宽度(字符)
    tableCol.width = width;
    //初始化表格,并添加默认的边框显示
    TableInit(&handle, &tableCol, table_default_border);
    //添加两行信息,每一列必须使用空格分开,并且有且只有一个
    TableAddCol(handle, TABLE_MODE_MIDDLE, "name id");
    TableAddCol(handle, TABLE_MODE_MIDDLE, "%s %s", "wang", "123456789");
    //显示表格
    TablePrint(handle);
    //销毁这个句柄
    TableDestroy(handle);

源代码

1. print_table.h文件

/**
 * @file  printf_table.h
 * @brief 表格显示数据
 * @author Dear_YG  https://blog.csdn.net/qq_42140292
 * @date 2023年7月24日
 * @note  
 */
 
#ifndef __PRINT_TABLE_H__
#define __PRINT_TABLE_H__

#define TABLE_BORDER_LENGTH 11

typedef void * TABLE_HANDLE;

typedef struct _TABLE_COL
{
    int count;//列数
    int *width;//每列的宽度(字符)
}TABLE_COL, *PTABLE_COL;

typedef enum _TABLE_MODE
{
    TABLE_MODE_LEFT = 0,
    TABLE_MODE_MIDDLE,
    TABLE_MODE_RIGHT
}TABLE_MODE;

//默认的边框显示
static char table_default_border[TABLE_BORDER_LENGTH] = { '*', '*', '*', '*', '+', '+', '+', '+', '-', '|', '+' };

/*
初始化表格信息
table       需要被初始化的句柄
tableCol    表格的行的信息
border      边界显示信息

border从左到右
  0    1   2    3    4    5   6    7     8     9       10
左上 右上 左下 右下 中上 中左 中右 中下 表格竖 表格横 表格中间
    0  8  4     1
    ┌ ─ ┬ ─ ┐
   9│    │    │
   5├ ─ ┼ ─ ┤6   ┼中间10
    │    │    │
    └ ─ ┴ ─ ┘
    2     7      3
    //备注 上面的表格符号无法使用,必须要ascii一个字符才行,或者修改源代码
*/
int TableInit(TABLE_HANDLE *table, PTABLE_COL tableCol,const char *border);

/*
表格添加一行
table       表格句柄
mode        表格内容显示位置  【0】靠左 【1】居中 【2】靠右
format      表格显示内容 【备注】需要使用空格分开,有且只有一个空格
*/
int TableAddCol(TABLE_HANDLE table, TABLE_MODE mode, char * format, ...);
void TablePrint(TABLE_HANDLE table);
void TableClean(TABLE_HANDLE table);
void TableDestroy(TABLE_HANDLE table);

#endif//__PRINT_TABLE_H__

2. print_table.c文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include "print_table.h"

typedef struct _TABLE
{
    char border[11];
    char *printStr;
    int strLen;
    int useLen;
    PTABLE_COL col;
}TABLE,*PTABLE;

int TableInit(TABLE_HANDLE *table, PTABLE_COL tableCol,const char * border)
{
    PTABLE pTable = (PTABLE)malloc(sizeof(TABLE) + sizeof(TABLE_COL) + sizeof(int)*tableCol->count);
    *table = pTable;
    
    pTable->useLen = 0;
    pTable->strLen = 10240;
    pTable->printStr = (char *)malloc(pTable->strLen);
    memset(pTable->printStr, 0, 10240);

    pTable->col = (PTABLE_COL)(pTable + 1);
    pTable->col->width = (int *)((char *)pTable + sizeof(TABLE) + sizeof(TABLE_COL));
    pTable->col->count = tableCol->count;
    for (int i = 0; i < pTable->col->count;i++)
    {
        pTable->col->width[i] = tableCol->width[i];
    }
    //pTable->c[0] = '┌';
    //pTable->c[1] = '┐';
    //pTable->c[2] = '└';
    //pTable->c[3] = '┘';
    //pTable->c[4] = '┬';
    //pTable->c[5] = '├';
    //pTable->c[6] = '┤';
    //pTable->c[7] = '┴';
    //pTable->c[8] = '─';
    //pTable->c[9] = '│';
    //pTable->c[10] = '┼';

    memcpy(pTable->border, border, TABLE_BORDER_LENGTH);

    return 0;
}

int FormatStr(char *str, int len)
{
    int strLen = strlen(str);
    if (strLen < len)
    {
        return len - strLen;
    }
    str[len] = 0;
    if (len == 2)
    {
        str[len - 1] = '.';
    }
    else if (len == 3)
    {
        str[len - 1] = '.';
        str[len - 2] = '.';
    }
    else if (len > 3)
    {
        str[len - 1] = '.';
        str[len - 2] = '.';
        str[len - 3] = '.';
    }
    return 0;
}

//mode 0 table 头  , 1 table 尾
void AddFrame(PTABLE pTable,int mode)
{
    int isFirstCol = 0;
    if (pTable->useLen == 0)
    {
        isFirstCol = 1;
    }

    if (isFirstCol)
    {
        sprintf(pTable->printStr + pTable->useLen, "%c", pTable->border[0]);
    }
    else
    {
        if (mode)
        {
            sprintf(pTable->printStr + pTable->useLen, "%c", pTable->border[3]);
        }
        else
        {
            sprintf(pTable->printStr + pTable->useLen, "%c", pTable->border[5]);
        }
        
    }
    pTable->useLen++;
    for (int i = 0; i < pTable->col->count; i++)
    {
        for (int j = 0; j < pTable->col->width[i]; j++)
        {
            sprintf(pTable->printStr + pTable->useLen, "%c", pTable->border[8]);
            pTable->useLen++;
        }
        if (i == pTable->col->count - 1)
        {
            if (isFirstCol)
            {
                sprintf(pTable->printStr + pTable->useLen, "%c\n", pTable->border[1]);
            }
            else
            {
                if (mode)
                {
                    sprintf(pTable->printStr + pTable->useLen, "%c\n", pTable->border[3]);
                }
                else
                {
                    sprintf(pTable->printStr + pTable->useLen, "%c\n", pTable->border[6]);
                }
            }
            pTable->useLen++;//多加了\n
        }
        else
        {
            if (isFirstCol)
            {
                sprintf(pTable->printStr + pTable->useLen, "%c", pTable->border[4]);
            }
            else
            {
                if (mode)
                {
                    sprintf(pTable->printStr + pTable->useLen, "%c", pTable->border[7]);
                }
                else
                {
                    sprintf(pTable->printStr + pTable->useLen, "%c", pTable->border[10]);
                }
            }
        }
        pTable->useLen++;
    }
    pTable->printStr[pTable->useLen] = 0;
}

int AddItem(PTABLE pTable, char *str, int len, int index, TABLE_MODE mode)
{
    int start = 0;
    int end = 0;
    int retLen = 0;
    sprintf(pTable->printStr + pTable->useLen, "%c", pTable->border[9]);
    pTable->useLen++;

    if (len)
    {
        if (mode == TABLE_MODE_LEFT)
        {
            end = len;
        }
        else if (mode == TABLE_MODE_MIDDLE)
        {
            start = len / 2;
            end = len - start;
        }
        else if (mode == TABLE_MODE_RIGHT)
        {
            start = len;
        }
    }

    for (int i = 0; i < start;i++)
    {
        sprintf(pTable->printStr + pTable->useLen, " ");
        pTable->useLen++;
    }
    retLen = sprintf(pTable->printStr + pTable->useLen, "%s", str);
    pTable->useLen += retLen;
    for (int i = 0; i < end; i++)
    {
        sprintf(pTable->printStr + pTable->useLen, " ");
        pTable->useLen++;
    }
    if (pTable->col->count == index + 1)
    {
        sprintf(pTable->printStr + pTable->useLen, "%c\n", pTable->border[9]);
        pTable->useLen += 2;
    }
    return 0;
}
#define ARG_BUFF_SIZE 2048
int TableAddCol(TABLE_HANDLE table, TABLE_MODE mode, char * format, ...)
{
    va_list args;
    int ret = 0;
    char buff[ARG_BUFF_SIZE] = { 0 };
    char *tmp = buff;
    PTABLE pTable = (PTABLE)table;
    int count = pTable->col->count;
    char * pStart = NULL;
    char * pTmp = NULL;
    char * pNext = NULL;

    va_start(args, format);
    int buffSize = ARG_BUFF_SIZE;
    ret = vsnprintf(tmp, buffSize - 1, format, args);
    if (ret > buffSize)
    {
        tmp = (char *)malloc(ret + 1);
        if (tmp == NULL)
        {
            return -1;
        }
    }
    vsprintf(tmp, format, args);
    pStart = tmp;
    
    AddFrame(pTable,0);
    for (int i = 0; i < count;i++)
    {
        pTmp = strstr(pStart, " ");
        if (pTmp)
        {
            *pTmp = 0;
            pTmp++;
            ret = FormatStr(pStart, pTable->col->width[i]);
            AddItem(pTable, pStart, ret, i, mode);
            pStart = pTmp;
        }
        else
        {
            ret = FormatStr(pStart, pTable->col->width[i]);
            AddItem(pTable, pStart, ret, i, mode);
            break;
        }
    }
    return 0;
}

void TablePrint(TABLE_HANDLE table)
{
    PTABLE pTable = (PTABLE)table;
    AddFrame(pTable, 1);
    printf("%s\n", pTable->printStr);
}

void TableClean(TABLE_HANDLE table)
{
    PTABLE pTable = (PTABLE)table;
    memset(pTable->printStr, 0, pTable->strLen);
    pTable->useLen = 0;
}

void TableDestroy(TABLE_HANDLE table)
{
    PTABLE pTable = (PTABLE)table;
    free(pTable->printStr);
    free(pTable);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值