2011-11-12 72 views
5

所以我正在做一個自定義的編輯控件。爲了跟蹤編輯控件的內容,我使用了一個動態分配的char數組。爲文本編輯控件實現緩衝區的最佳方式是什麼?

  • 現在,我知道我需要在 某些情況下,當用戶點擊一個特定的 點,如數組中間插入。所以,我在想,我可以使用 std :: vector,而不是字符數組,因此我可以使用.insert函數,而且 也不需要太在意內存管理。
  • 我也在考慮可能直接將輸入流存儲到一個 字的數組/向量中(不保留連續緩衝區),因爲我的 的全部用途是實現語法高亮顯示。

哪個會是更好的方法去處理事情?爲什麼?

回答

4

對於具有今天計算機的文本緩衝區,您確實可以使用單個連續緩衝區(例如向量),因爲CPU速度足夠快以便插入時間(使用這種天真方法進行o(n)操作)仍然是一個可行的選項。

在過去,當計算機慢幾千倍時,常用的簡單方法是將文本保留在緩衝區中,但是與光標位置相對應的「孔」,以便插入一個o(1)操作並從一側移動字符當光標在文本中移動時(基本上使光標移動一個o(k)操作,其中k是跳過的字符數)。

對於爲程序員設計的編輯器,文本將按邏輯線進行細分,因此使用基於指向線的指針數組的方法似乎是合適的。即使這會使一些交叉操作有些惱人,一些基於行的操作會變得更容易...顯示中的行編號變成了一個微不足道的問題,特別是如果您不需要實現換行(無論如何都是代碼很糟糕)通過截斷和水平滾動代替。

+0

這是一個非常好的解釋,謝謝!是的,文本將被劃分爲邏輯線,並且我正在進行水平滾動。 – devjeetroy

+2

在編輯大量文件(如日誌文件)時,使用一個連續緩衝區的編輯器遭受可怕的損失。對於源文件很好,但人們不可避免地想要在他們的編輯器中加載_everything_。因此需要某種分割。 –

2

您可能需要一個雙重表示,所以同時擁有一個char向量和一個單詞向量(問題是讓它們保持同步)。

我建議你也在尋找,甚至可能使用一些圖形化的工具包,這些工具包的源代碼可以免費使用,並且可以自定義。 (我不是Windows的傢伙,但是)我想, Qt這是在Windows,Linux,MacOSX上運行的C++中的開源圖形庫...

我忍不住了,因爲我不知道我不用Windows(我所有的機器都是在Linux下)。

+0

感謝您的答覆男人!一旦我完成了我自己的事情,我一定會考慮他們。我想首先了解所有「引擎蓋下」的東西。我也在想,可能需要雙重代表。這會對性能/內存使用情況產生影響嗎? 如何保持字符矢量,以及每個單詞的位置矢量?像起始位置和長度(使用結構)?這會更好地表現明智嗎? – devjeetroy

+0

**過早的優化是邪惡的**所以首先代碼使用分析它正確實施,基準測試,然後對其進行優化 –

+0

其實,我只是想,我應該用代碼去的觀點,讓我不要「T結束時,它能夠被輕鬆地通過選擇正確的方法解決問題 – devjeetroy

4

最好的方法是從系統編輯或財富控制開始,並根據需要進行調整。編寫自己的編輯控件比您可能意識到的還要多 - 包括處理可訪問性,複雜字母語言的IME,複製和粘貼,滾動條,光標,選擇等等。

這兩個系統控件提供了許多擴展點,這些擴展點應該可以實現大多數目標。除非你真的建立一個文字處理或源代碼編輯器,你應該堅持提供的。自定義編輯控件是一個巨大的錯誤來源。我很少看到一個適用於基本案例的作品。

馬丁

+0

我正在構建一個源代碼編輯器。我已經嘗試過richedit,並且它的子類化速度並不像我希望的那樣快。我用over-write和setcharformat方法,但他們不是很整潔,可以說。我已經開始使用自定義編輯控件,並且已經實現了光標和多行輸入。所以,現在我正在努力使其準備文本選擇,多選線和東西 – devjeetroy

+0

如果你真的建立一個源代碼編輯器,然後實現自己的緩衝區是正確的想法。大多數源代碼編輯器會被要求加載非常大的文件(例如服務器日誌),因此請確保您認真考慮基本操作的O大擴展性。 –

+0

是的,謝謝你!這是我的主要考慮因素之一 – devjeetroy

3

如果你正在考慮像源代碼查看器(參見:「落實語法高亮」)與一個可變的後備存儲,你可能會發現std::list<std::string>一個很好的起點,它可能是矯枉過正,如果字符串很小。

對於您的文本(例如一個大的std::stringstd::vector),您可以在編輯過程中進行大量移動和調整大小,以及在重新定位時進行大量掃描。這些移動和調整將導致許多大的連續分配,緩衝區初始化,移動和釋放舊內存。它也限制了你如何緩存數據(如果這很重要)。您的查找時間會比列表慢一些,但是您的移動和突變速度將比使用整個文件的連續緩衝區快得多。

std::list<std::string>有一些很好的性質,因爲它生長和變異爲字符串(例如,對於每行或段)很好的集合。

此概要細節列表中的優勢,並將其與其他容器得好:http://www.cplusplus.com/reference/stl/list/

如果你希望將一些數據關聯的字符串/線,那麼就創建這些列表:

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

在搜索同一薄我跨在那裏非常有幫助2個維基百科頁面傳來:

Gap buffer進行簡單的編輯

Rope (data structure)複雜的文本編輯

+0

我在cpp中的間隙緩衝區嘗試:https://github.com/cmaughan/gapbuffer – cmaughan

相關問題