Freder的博客

如何用C语言写一个多行输入函数

· Freder · Code ·

从高中毕业就开始研究Editor,想写一个自己的文本编辑器。
大一时不了解其他东西就想用控制台写一个,留下了这么一个不完备的多行输入函数。

1. 准备

在尝试实现这个函数的过程中,我试过printf()系列,也试过getchar()系列,还有getch()系列……后来发现回车入栈函数并不能满足多行文本输入的需求,最后找到了_getch()_putch()。由于char类型不能容纳中文(2个字节),选择了wchar_t作为储存字符的类型,与之相匹配的函数是void _putwch(wchar_t c)wchar_t _getwch()

现在可以很容易实现输入一个字符并输出:

wchar_t ch = _getwch();
_putwch(ch);

2. 架构

2.1. 基本数据结构

  • Edit box config

    struct EditBoxConfig {
        char *filename;
        short cursor_x, cursor_y;
        short screen_rows, screen_cols;
        struct Word *head_word;
        // Head_word has no characters(WEOF) which follows by the text.
    };
    
  • Word

    我使用了双向链表来储存输入字符,但也可以尝试char *这样的数组配合mallocrealloc来写,理论上是更好的选择。

    struct Word {
        wchar_t ch;
        struct Word *last;
        struct Word *next;
    };
    

2.2. 输入

  • 输入函数需要正确处理输入的内容:

    wchar_t ch;
    switch (ch = _getwch()) {
        // You can find the number of these characters on the Internet.
        case ARROW_KEY:
            move_pointer(_getwch());
            break;
        case BACKSPACE:
            delete_word();
            break;
        case ...:
            /* You can do what you want.*/
            break; 
        default: /* Word and enter. */
            insert_word(ch);
            break;
    }
    
  • 在输入过程中需要定义一个present_word在储存当前指向的字符。我们可以将它看作虚拟光标。

2.3. 输出

  • 输出需要在正确的位置渲染出字符:

    // This is print word head.
    // If the text is beyond the screen, 
    // it will not be the head of text.
    struct Word *word = word_head;
    
    // Print line by line.
    for (i = 0; i < editor.screen_rows - 1; i++) {
        // If current Word is a word, print it on screen.
        // Else if current Word is newline character, print space after this position.
        print_word_and_update_cursor();
    }
    
    move_cursor_to(editor.cursor_x, editor.cursor_y);
    

2.4. 输入、输出函数联系

  • while (1) {
        refresh_screen();
        process_keypress();
    }
    

3. 想说的话(吐槽=。=

从开始这个项目到现在很久很久了,最主要的问题是我很少找到可以借鉴的资料,导致战线超级长。这也从另一方面反映这东西的奇葩(=。=)

从一开始的想写一个自己的文本编辑器,到和编辑框杠上,有很多可以回忆的往事。所以虽然这东西简单,但我很想记录下来,它对我来说是非常重要的回忆。记得几次寒假一两周不出门,每天十几小时花在上面都是辛酸泪。

另外,我的Demo还有很多功能没有实现。比如:翻页、一些常用键功能……短期内不会再弄这东西了。

4. 参考资料

  1. My demo in github
  2. Kilo
  3. Kilo解析

本文遵循 CC BY-ND-ND 3.0 协议,转载请注明原作者,禁止商用,禁止演绎。


© 2017 - 2019 Freder
Hexo 强力驱动 · 主题 Milk