ASCII 数字的例子

之前的文章【参考1】,介绍了 ASCII 的字体,这次用这个实现在 Console 下显示数值。使用 VS2019 VC 编译通过。

运行结果如下:

测试代码如下:

// AsciiFontTest.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <windows.h>  // 必须包含头文件
#include <iostream>

// 字体宽度
#define DOHWIDTH  20
#define DOHHEIGHT 16

// 定义二维数组,每行预留足够空间
char DOH[10][DOHHEIGHT*10][DOHWIDTH+1] = {
// char "0"
{
"     000000000      ",
"   00:::::::::00    ",
" 00:::::::::::::00  ",
"0:::::::000:::::::0 ",
"0::::::0   0::::::0 ",
"0:::::0     0:::::0 ",
"0:::::0     0:::::0 ",
"0:::::0 000 0:::::0 ",
"0:::::0 000 0:::::0 ",
"0:::::0     0:::::0 ",
"0:::::0     0:::::0 ",
"0::::::0   0::::::0 ",
"0:::::::000:::::::0 ",
" 00:::::::::::::00  ",
"   00:::::::::00    ",
"     000000000      "
},
// char "1"
{
"       1111111      ",
"      1::::::1      ",
"     1:::::::1      ",
"     111:::::1      ",
"        1::::1      ",
"        1::::1      ",
"        1::::1      ",
"        1::::l      ",
"        1::::l      ",
"        1::::l      ",
"        1::::l      ",
"        1::::l      ",
"     111::::::111   ",
"     1::::::::::1   ",
"     1::::::::::1   ",
"     111111111111   "
},
// char "2"
{
" 222222222222222    ",
"2:::::::::::::::22  ",
"2::::::222222:::::2 ",
"2222222     2:::::2 ",
"            2:::::2 ",
"            2:::::2 ",
"         2222::::2  ",
"    22222::::::22   ",
"  22::::::::222     ",
" 2:::::22222        ",
"2:::::2             ",
"2:::::2             ",
"2:::::2       222222",
"2::::::2222222:::::2",
"2::::::::::::::::::2",
"22222222222222222222",
},
// char "3"
{
" 333333333333333    ",
"3:::::::::::::::33  ",
"3::::::33333::::::3 ",
"3333333     3:::::3 ",
"            3:::::3 ",
"            3:::::3 ",
"    33333333:::::3  ",
"    3:::::::::::3   ",
"    33333333:::::3  ",
"            3:::::3 ",
"            3:::::3 ",
"            3:::::3 ",
"3333333     3:::::3 ",
"3::::::33333::::::3 ",
"3:::::::::::::::33  ",
" 333333333333333    ",
},
// char "4"
{
"        444444444   ",
"       4::::::::4   ",
"      4:::::::::4   ",
"     4::::44::::4   ",
"    4::::4 4::::4   ",
"   4::::4  4::::4   ",
"  4::::4   4::::4   ",
" 4::::444444::::444 ",
" 4::::::::::::::::4 ",
" 4444444444:::::444 ",
"           4::::4   ",
"           4::::4   ",
"           4::::4   ",
"         44::::::44 ",
"         4::::::::4 ",
"         4444444444 ",
},
// char "5"
{
" 555555555555555555 ",
" 5::::::::::::::::5 ",
" 5::::::::::::::::5 ",
" 5:::::555555555555 ",
" 5:::::5            ",
" 5:::::5            ",
" 5:::::5555555555   ",
" 5:::::::::::::::5  ",
" 555555555555:::::5 ",
"             5:::::5",
"             5:::::5",
" 5555555     5:::::5",
" 5::::::55555::::::5",
"  55:::::::::::::55 ",
"    55:::::::::55   ",
"      555555555     ",
},
// char "6"
{
"         66666666   ",
"        6::::::6    ",
"       6::::::6     ",
"      6::::::6      ",
"     6::::::6       ",
"    6::::::6        ",
"   6::::::6         ",
"  6::::::::66666    ",
" 6::::::::::::::66  ",
" 6::::::66666:::::6 ",
" 6:::::6     6:::::6",
" 6:::::6     6:::::6",
" 6::::::66666::::::6",
"  66:::::::::::::66 ",
"    66:::::::::66   ",
"      666666666     ",
},
// char "7"
{
"77777777777777777777",
"7::::::::::::::::::7",
"7::::::::::::::::::7",
"777777777777:::::::7",
"           7::::::7 ",
"          7::::::7  ",
"         7::::::7   ",
"        7::::::7    ",
"       7::::::7     ",
"      7::::::7      ",
"     7::::::7       ",
"    7::::::7        ",
"   7::::::7         ",
"  7::::::7          ",
" 7::::::7           ",
"77777777            ",
},
// char "8"
{
"      888888888     ",
"    88:::::::::88   ",
"  88:::::::::::::88 ",
" 8::::::88888::::::8",
" 8:::::8     8:::::8",
" 8:::::8     8:::::8",
"  8:::::88888:::::8 ",
"   8:::::::::::::8  ",
"  8:::::88888:::::8 ",
" 8:::::8     8:::::8",
" 8:::::8     8:::::8",
" 8:::::8     8:::::8",
" 8::::::88888::::::8",
"  88:::::::::::::88 ",
"    88:::::::::88   ",
"      888888888     "
},
// char "9"
{
"      999999999     ",
"    99:::::::::99   ",
"  99:::::::::::::99 ",
" 9::::::99999::::::9",
" 9:::::9     9:::::9",
" 9:::::9     9:::::9",
"  9:::::99999::::::9",
"   99::::::::::::::9",
"     99999::::::::9 ",
"          9::::::9  ",
"         9::::::9   ",
"        9::::::9    ",
"       9::::::9     ",
"      9::::::9      ",
"     9::::::9       ",
"    99999999        "
}
};

// 计算 n 的位数
// 比如: 123 返回2, 1 返回0
int count_digits(int n) {
    // 处理特殊情况:0的位数为1
    if (n == 0) return 0;  // [^1]

    int count = 0;
    n = abs(n);  // 处理负数

    while (n != 0) {
        n /= 10;  // 每次循环移除最后一位
        count++;
    }
    return count-1;
}

/**
 * @brief 获取整数指定位的数字
 * @param v 目标整数(支持负数)
 * @param index 位索引(0表示个位,1表示十位,依此类推)
 * @return int 对应位的数字(0-9)
 *
 * @example
 * GetValueOf(1234, 0) -> 4
 * GetValueOf(-987, 2) -> 9
 */
int GetValueOf(int v, int index) {
    if (index < 0) return 0;  // 非法索引处理
    v = abs(v);               // 处理负数情况[^1]

    long long divisor = 1;    // 使用long long防止溢出
    for (int i = 0; i < index; ++i) {
        divisor *= 10;
        if (divisor > INT_MAX) return 0; // 大索引保护机制[^2]
    }

    return (v / divisor) % 10;
}

char* Int2Ascii(int value) {
    // 计算最终的宽度
    int StrWitdh = (count_digits(value)+1) * DOHWIDTH + 1; // 最后加入回车换行字符

    char *str =(char*) malloc(StrWitdh * DOHHEIGHT + 1); //末尾使用 \0 作为标记
    if (str == NULL) {
        return NULL;
    } else  memset(str, '*', StrWitdh * DOHHEIGHT + 1);
    str[StrWitdh * DOHHEIGHT + 1 - 1] = NULL;

    // 赋值换行
    for (int i = 1; i < DOHHEIGHT+1; i++) {
        str[i * StrWitdh - 1] = '\n';
    }

    // 从 Value 的最高位开始搬移
    for (int i = 0; i<count_digits(value)+1; i++)
    {
        printf("GetValueOf[%d,%d]=%d\n", value, count_digits(value) - i, GetValueOf(value,count_digits(value)-i));
        for (int j = 0; j < DOHHEIGHT; j++) {
            memcpy(&str[j* StrWitdh+ DOHWIDTH*i], &DOH[GetValueOf(value, count_digits(value)-i)][j][0], DOHWIDTH);
            //printf("copy DOH[%d][%d][0] > str[%d]\n", GetValueOf(value, count_digits(value) - i), j, j * StrWitdh + DOHWIDTH * i);
           
        }
    }


    
    return str;
}
int main()
{
    for (int i = 0; i < 100; i++) {
        char* p = Int2Ascii(i);
        printf("%s\r\n", p);
        free(p);
        Sleep(500);
    }        
    
}

参考:

1.https://www.lab-z.com/asciiart/

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注