为文本编辑控件实现缓冲区的最佳方法是什么?

What is the best way to implement a buffer for a text edit control?

本文关键字:最佳 方法 是什么 缓冲区 文本编辑 控件 实现      更新时间:2023-10-16

所以我正在制作一个自定义编辑控件。为了跟踪编辑控件的内容,我使用了一个动态分配的字符数组。

  • 现在,我知道我需要插入到数组的中间某些情况下,例如当用户单击特定的点。所以,我在想,不用字符数组,我可以用Std::vector,所以我将能够使用。insert函数,也不需要关心内存管理。
  • 我也在想也许直接将输入流存储到数组/向量的字(不保持一个连续的缓冲区),因为我的这样做的全部目的是实现语法高亮。

哪一种处理事情的方法更好?,为什么?

对于今天的计算机,您确实可以使用单个连续缓冲区(例如矢量),因为cpu足够快,使插入时间(这种朴素方法的o(n)操作)仍然是一个可行的选择。

在过去,当计算机速度慢了几千倍的时候,一种常见的简单方法是将文本保存在缓冲区中,但是有一个与光标位置相对应的"洞",当光标在文本中移动时,将插入操作变为o(1)操作,并将字符从洞的一侧移动到另一侧(基本上使光标移动为o(k)操作,其中k是跳过的字符数)。

对于为程序员设计的编辑器,文本将被细分为逻辑行,因此使用基于行指针数组的方法似乎是合适的。即使这将使一些跨线操作有些烦人,但一些基于线的操作将变得更容易……显示中的行编号成为一个微不足道的问题,特别是如果您不需要通过截断和水平滚动来实现行换行(无论如何对代码来说都很可怕)。

最好的方法是从系统编辑或富编辑控件开始,并使其适应您的需要。编写自己的编辑控件比你可能意识到的要多得多——包括处理可访问性、复杂字母语言的ime、复制和粘贴、滚动条、光标、选择等等。

这两个系统控件提供了许多扩展点,应该允许您实现大多数目标。除非您真的要构建一个文字处理或源代码编辑器,否则您应该坚持使用所提供的那些编辑器。自定义编辑控件是大量bug的来源。我很少看到一个只适用于基本情况的。

Martyn

如果您正在考虑使用可变后备存储的源代码查看器(ref: "实现语法高亮显示")之类的东西,您可能会发现std::list<std::string>是一个很好的起点,如果字符串很小,它可能是多余的。

有一个连续的缓冲区为您的文本(例如一个大的std::stringstd::vector),你将有很多的移动和调整大小在编辑期间,以及大量的扫描时重新定位。这些移动和调整大小将导致许多大的、连续的分配、缓冲区初始化、移动和释放旧内存。它还限制了缓存数据的方式(如果这很重要的话)。使用列表的查找时间会稍微慢一些,但是移动和更改将比使用整个文件的连续缓冲区快得多。

std::list<std::string>有一些很好的属性,因为它可以很好地作为字符串集合(例如每一行或每一段)生长和突变。

这个概述详细介绍了list的优点,并将其与其他容器进行了比较:http://www.cplusplus.com/reference/stl/list/

如果您想将一些数据关联到字符串/行,那么只需创建以下列表:

namespace MON {
class t_line {
public:
  /* ... */
private:
  std::string d_string;
  t_lexer_stuff d_lexerStuff;
};
}

在搜索同样的内容时,我发现了两个非常有用的维基百科页面:

用于简单编辑的空白缓冲区

Rope(数据结构)用于复杂文本编辑

您可能需要双重表示,因此同时拥有char向量和words向量(问题是保持它们同步)。

我还建议寻找,甚至使用一些图形工具包,其源代码是免费提供的,并且可以自定义。(我不是Windows的家伙,但是)我在想Qt,这是一个用c++编写的开源图形库,运行在Windows、Linux、MacOSX……

我不能帮助更多,因为我不知道,我不使用Windows(我所有的机器都是Linux)。