从高中毕业就开始研究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; };
- Word我使用了双向链表来储存输入字符,但也可以尝试
char *
这样的数组配合malloc
和realloc
来写,理论上是更好的选择。
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. 参考资料
Freder
2018 年 3 月 10 日
原文链接:如何用C语言写一个多行输入函数