在C语言中生成Ascii艺术文本

7

我正在尝试为一个有趣的应用程序生成ASCII艺术文本。我从FIGLET得到了ASCII模式。我在printf语句中使用该模式来打印字母。这是我从FIGLET获得的模式截图:

FIGLET

这是我用来打印A的代码片段:

printf("      _/_/\n   _/    _/\n  _/_/_/_/\n _/    _/\n_/    _/\n");

现在,我从用户那里获取输入文本,并展示成ASCII艺术。由于我使用的是printf,所以只能垂直生成:

Vertical image

但是我需要横向的ASCII艺术。如何做到这一点呢?

4个回答

3

是的,这是一个众所周知的问题。我上次解决这个问题的方法是为每一行使用一个数组,并单独渲染每个字母。

首先,我会用数组来表示每个字母。例如,你的A会像这样:

char* letter[8]; 
letter[0] = "      _/_/ ";
letter[1] = "   _/    _/";
etc.

实际上,将使用2D数组,每个字母位于不同的索引位置。

实际渲染也将在一个数组中进行,类似于:

char* render[8];

然后使用连接来构建每一行。一个简单的嵌套循环就可以完成任务:

for each line, i to render (i.e the height of the letters)
    for each letter, j
       concatenate line i of letter j to the to char* i in the array

最后遍历数组并打印每一行。事实上,您可以跳过渲染数组,直接打印每一行而不带换行符。以下是一个示例:
for each line, i to render : // (i.e the height of the letters) 
    for each letter, j {
       output line i of letter j
    }
    output a carriage return
}

我的C语言有些生疏,所以这里是“伪代码”。但是,我认为我的逻辑是正确的。


(顺带一提,使用上述内容作为基础,您实际上可以构建 ASCII 艺术字体文件并根据需要将其加载到数组中。) - Jaco Van Niekerk
使用二维数组完成了它...但在空间填充方面遇到了一些问题..希望我能很快解决它.. - utsabiem

2
你可以尝试以下方法:

注意:显然,以下代码缺乏许多东西,例如内存释放、错误检查、不完整的代码等。这个想法是给你一个提示!

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

#define ROW 4
#define COL 8
#define CHAR_INDEX_MAX 26

enum alph_enum {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z};

typedef struct _alphabets {
    char *line[ROW];
}alphabet;

alphabet chars[26];

init_a(enum alph_enum letter)
{
    int i;
    for (i=0 ; i<ROW ; i++) {
        chars[letter].line[i] = (char *) malloc(COL);
        if (chars[letter].line[i] == NULL) {
            printf("memory allocation failed \n");
            return;
        }
    }

    switch (letter) {
                                     /*0123 4567*/
    case H:
        strcpy(chars[letter].line[0], "|       |");
        strcpy(chars[letter].line[1], "|_______|");
        strcpy(chars[letter].line[2], "|       |");
        strcpy(chars[letter].line[3], "|       |");
        break;
    case E:
        strcpy(chars[letter].line[0], "|-------");
        strcpy(chars[letter].line[1], "|_______");
        strcpy(chars[letter].line[2], "|       ");
        strcpy(chars[letter].line[3], "|_______");
        break;
    case L:
        strcpy(chars[letter].line[0], "|       ");
        strcpy(chars[letter].line[1], "|       ");
        strcpy(chars[letter].line[2], "|       ");
        strcpy(chars[letter].line[3], "|_______");
        break;
    /*  for all the other alphabets */
    }

    return;

}

print_str(char word[])
{
    int i, j;

    printf("\n");
    for (i=0; i<ROW; i++) {
        for (j=0 ; j<strlen(word) ; j++) {
            printf("%s", chars[word[j] % 'A'].line[i]);
        }
        printf("\n");
    }
    printf("\n");

    return;
}


int main(void)
{
    init_a(H);
    init_a(E);
    init_a(L);
    /* print_str("HELLO"); */
    print_str("HELL");
    return 0;

    /* free the memory for HEL here */
}

输出结果如下:
> gcc test.c -o print
> print

|       ||-------|       |
|_______||_______|       |
|       ||       |       |
|       ||_______|_______|_______

>

待完成:

  • 您可以包括数字、特殊字符(如!、@、#、$等)、空格,也可以使用所有ASCII字符。
  • 您可以支持字符的加粗、斜体、下划线和高亮。
  • 您可以支持前景色和背景色。
  • 您可以支持动画效果。

希望这有所帮助!


谢谢,让我试试看... 我想Jaco Van提到过类似的想法。 - utsabiem

1

不要将整个字符作为一个字符串一次性打印出来,而是将字符分成多个字符串--每行文本一个字符串。然后打印每个字符的第一行,换行,然后是每个字符的第二行等等。您需要用空格填充行以确保它们都具有正确的宽度。


1
很高兴看到你喜欢Figlet。你展示的Figlet小部件实际上包含一个命令行工具,可以生成ASCII输出。http://www.figlet.org/ 它也可以通过brew Link轻松安装。
你可以通过popen(..)或类似的方式在自己的程序中轻松捕获其输出。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接