您的位置:首页 > 编程语言 > C语言/C++

C语言实现控制台输出表格样式格式化

2016-09-14 12:49 495 查看

控制台表格输出需求

在研发工具时,尤其是一些服务后台管理性质的工具时,经常会遇到使用控制台进行命令行方式操作的需求,在控制台使用表格将一些结果有组织地反馈给工具使用者,是一个必要的功能,本文将给出一个用于实现控制台输出表格样式格式化的C语言代码,希望可以帮助到有此方面需求的小伙伴们。

C语言实现

table.h定义表格结构体和format_table方法实现表格样式格式化:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
typedef struct TABLE {
unsigned int row_num;
unsigned int col_num;
unsigned int *col_max_width;
char ***content;
} table;

extern void format_table(table *t, char *formated_out);


通过table 设置表格的行数、列数以及对象行列索引的文本数据,formated_out为格式化完成的字符串。

table.c实现表格样式格式化逻辑:

#include "table.h"

#define CORNER_FLAG "+"
#define ROW_LINE "-"
#define COL_PADDING " "
#define COL_LINE "|"

/**
* 计算在控制台中输出的字符串长度
* str 字符串
**/
static int str_len(unsigned char *str){
int len = 0;
int offset = 2;
int word_len = strlen(str);
int i = 0;

for(i; i < word_len; i++){
if(str[i] < 128){
len += 1;
} else {
len += 2;
i += offset;
}
}
return len;
}
/**
* 生成表格行边
* col_width 表格的列宽
* col_num 表格列数
* edge 保存行边字符串
**/
static void make_edge(const unsigned int *col_width, const unsigned int col_num, char *edge){
memset(edge, 0 ,sizeof(edge));
strcat(edge, CORNER_FLAG);
int col_line_counter;
int row_line_counter;
for( col_line_counter = 0; col_line_counter < col_num; col_line_counter++ ){
strcat(edge, ROW_LINE);
for( row_line_counter = 0; row_line_counter < col_width[col_line_counter]; row_line_counter++ ){
strcat(edge, ROW_LINE);
}
strcat(edge, ROW_LINE);
strcat(edge, CORNER_FLAG);
}
strcat(edge, "\n");
}

/**
* 根据表格一列的宽度值,求出该列中最大的宽度
* col_width 指向一列所有宽度值数组的指针
* row_num 表格行数
* return 最大宽度值
**/
static int get_max_col_width(int *col_width, const unsigned int row_num){
int max_col_width = 0;
int i = 0;
for(i; i < row_num; i++){
if( max_col_width < col_width[i]){
max_col_width = col_width[i];
}
}
return max_col_width;
}

/**
* 根据表格列的宽度,求出每列最大的宽度
* col_width 指向表格所有列宽度二维数组的指针
* row_num 表格行数
* col_num 表格列数
* max_col_width 指向table结构体中的col_max_width的指针,用于保存表格每列最大的宽度
**/
static void get_max_col(int **col_width, const unsigned int row_num, const unsigned int col_num, int *max_col_width){
int i;
int j;
for(i = 0; i < col_num; i++){
int max_width[ row_num ];
for(j = 0; j < row_num; j++){
max_width[j] = *((int *)col_width + (j * col_num) + i);
}
max_col_width[i] = get_max_col_width(max_width, row_num);
}
}

/**
* 得到表格中所有列的宽度值
* t 指向表格结构体的指针
* col_width 指向表格所有列宽度二维数组的指针,用于保存所有宽度值
**/
static void get_col_width(table *t, int **col_width){
int i = 0;
int j;
for(i; i < t->row_num; i++){
for(j = 0; j < t->col_num; j++){
*((int *)col_width + i * t->col_num + j) = str_len(t->content[i][j]);
}
}
}

/**
* 设置table结构体中col_max_width
* t 指向表格结构体的指针
**/
static void set_table_col_max_width(table *t){
int col_width[t->row_num][t->col_num];
get_col_width(t, (int **)col_width);
get_max_col((int **)col_width, t->row_num, t->col_num, t->col_max_width);
}

/**
* 得到表格的总宽
* t 指向表格结构体的指针
**/
static int get_table_width(table *t){
int col_padding_width = 2 * t->col_num;
int col_line_width = t->col_num + 1;
int col_width = 0;
int i;
for(i = 0; i < t->col_num; i++){
col_width += t->col_max_width[i];
}
return col_line_width + col_padding_width + col_width;
}

/**
* 设置格式化表格中的空格
* str 保存的字符串
* space_num 空格的数量
**/
static void set_space_txt(char *str, const unsigned int space_num){
int i;
for(i = 0; i < space_num; i++){
strcat(str, " ");
}
}

/**
* 生成表格行边
* row_id 行id
* t 指向表格结构体的指针
* row_txt 格式化输出的表格行边字符串
**/
static void make_row(const unsigned int row_id, table *t, char *row_txt){
int i;
memset(row_txt, 0, sizeof(row_txt));
strcat(row_txt, COL_LINE);
for(i = 0; i < t->col_num; i++){
strcat(row_txt, COL_PADDING);
int word_len = str_len(t->content[row_id][i]);
strcat(row_txt, t->content[row_id][i]);
set_space_txt(row_txt, t->col_max_width[i] - word_len);
strcat(row_txt, COL_PADDING);
strcat(row_txt, COL_LINE);
}
}

/**
* 格式化表格方法
* t 指向表格结构体的指针
* formated_out 格式化输出字符串
**/
void format_table(table *t, char *formated_out){
set_table_col_max_width(t);
int col_width = get_table_width(t);
char row_txt[col_width + t->col_num];
int i;

make_edge(t->col_max_width, t->col_num, row_txt);
strcat(formated_out, row_txt);

for( i = 0; i < t->row_num; i++){
make_row(i, t, row_txt);
strcat(formated_out, row_txt);
strcat(formated_out, "\n");
make_edge(t->col_max_width, t->col_num, row_txt);
strcat(formated_out, row_txt);
}
}


实现效果

int main(){

table t;

t.row_num = 5;
t.col_num = 3;

t.col_max_width = (int *)malloc(sizeof(int) * t.col_num);
t.content = (char ***)malloc(sizeof(char **) * t.row_num);
t.content[0] = (char **)malloc(sizeof(char *) * t.col_num);
t.content[1] = (char **)malloc(sizeof(char *) * t.col_num);
t.content[2] = (char **)malloc(sizeof(char *) * t.col_num);
t.content[3] = (char **)malloc(sizeof(char *) * t.col_num);
t.content[4] = (char **)malloc(sizeof(char *) * t.col_num);

t.content[0][0] = "AAAAAAAAAAAAAAAAA";
t.content[0][1] = "test";
t.content[0][2]= "BB";

t.content[1][0] = "2";
t.content[1][1] = "CCCCCCCCCCCCCCCCCCCCCCCCC";
t.content[1][2]= "测试";

t.content[2][0] = "3";
t.content[2][1] = "EEEEEEEEEEEEEE";
t.content[2][2] = "FFFFFFFFFFFFFFF测试FFFFFFF";

t.content[3][0] = "GGGGGGGGGGGGGGGG";
t.content[3][1] = "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH";
t.content[3][2]= "III";

t.content[4][0] = "GGGGGGGGGGGGGGG";
t.content[4][1] = "KKKKKKKKKKKKKKKKKKKK";
t.content[4][2] = "LLLLLLLLLLLLLLLLLLLLLLLLL";

char formated_out[2048];
memset(formated_out, 0, 2048);
format_table(&t, formated_out);

printf("%s", formated_out);

free(t.col_max_width);
free(t.content[0]);
free(t.content[1]);
free(t.content[2]);
free(t.content[3]);
free(t.content[4]);
free(t.content);

return 0;
}


控制台输出表格样式效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: