16

わかりました、これはちょっと生意気な質問です。シンプルなテキスト エディタを作成したい (独自のテキスト モード画面処理を使用)。テキスト バッファを表すために使用できるデータ構造の良い例と、文字/テキストの挿入/削除の簡単な例が欲しいだけです。残りのコードはすべて自分で処理できます (ファイル I/O、コンソール I/O など)。シンプルなエディタ ソースへのリンクがあると便利です (C または C++)。

4

11 に答える 11

15

私は、主な製品がテキスト エディターである会社で働いていました。そのためのスクリプト言語を主に担当しましたが、当然、エディタ自体の内部設計も大きな話題になりました。

それは、2 つの一般的な思考の流れに分かれているように見えました。1 つは、各行を単独で保存してから、それらをリンク リストまたはその他の満足のいく全体的なデータ構造にリンクするというものでした。利点は、行単位の編集アクション (行全体の削除、ファイル内の行ブロックの移動など) を実装するのは簡単ではなく、したがって非常に高速であることです。欠点は、ファイル全体をトラバースしてこれらのデータ構造を構築する必要があるため、ファイルの読み込みと保存に少し手間がかかることでした。

当時のもう 1 つの考え方は、テキストが変更されていない場合は改行に関係なく、テキストの塊をまとめて保持し、編集で必要な場合にのみ分割することでした。利点は、ファイルの未編集の塊を非常に簡単にファイルに書き出すことができることでした。ファイルをロードし、1 行を変更し、ファイルを保存するという単純な編集は、非常に高速でした。欠点は、これらのテキストの塊を解析し、大量のデータを移動する必要があるため、行指向または列ブロック操作の実行に非常に時間がかかることでした。

私たちは常にライン指向のデザインにこだわっており、その価値が何であれ、私たちの製品は当時最速のエディターの 1 つと見なされていました。

于 2008-09-30T18:41:46.427 に答える
9

「Gang of Four」の本 ( Design Patterns ) には、例の主な情報源として GUI ベースのテキスト エディターがあり、所有する価値のある本です。

一般的な「純粋なテキスト」エディタはおそらく、SGI の STL が実装しているロープを使用します。基本的に、それらは文字バッファーのリンクされたリストです。このように、文字の挿入/削除には、ドキュメント全体を単一のバッファーに格納してすべてをシフトするのではなく、小さなバッファーといくつかのポインターを変更する必要があります。

于 2008-09-30T18:22:33.633 に答える
8

これは 2008 年です。テキスト エディタを作成しないでください。あなたは火を再発明しています。

まだここ?これが当てはまるかどうか、またはどのプラットフォームをサポートする予定かはわかりませんが、Neatpad シリーズのチュートリアルは、テキスト エディターの作成について考え始めるのに最適な場所です。彼らは基本的なプラットフォームとして Win32 に焦点を当てていますが、学んだ教訓の多くはどこにでも当てはまります。

于 2008-09-30T21:07:11.570 に答える
8

私のお気に入りのソリューションはギャップ バッファーです。これは、実装が非常に簡単で、償却効率が優れているためです。ギャップとして指定された領域で、単一の文字配列を使用するだけです。概念を理解すれば、コードはほとんど自然に続きます。

また、テキストの特定の行を簡単に抽出できるように、各行の先頭のインデックスを追跡するための補助配列 [vector<int>] も必要です。補助配列は、ギャップが移動したとき、または改行が挿入/削除されたときにのみ更新する必要があります。

于 2008-09-30T21:35:33.687 に答える
5

これら 2 つのオンライン ドキュメントは、小さいながらも、テキスト エディターにとって「よく知られた」データ構造/テクニックの宝庫です。

  1. Data Structures for Text Sequencesでは、いくつかのデータ構造について説明し、実験的に分析しており、最適なデータ構造としてピース テーブルに傾いています。ただし、Net.wisdom は、テキスト編集には十分であり、実装/デバッグが簡単であるため、ギャップ バッファーに傾いているようです。
  2. 「テキスト編集の技術」(www.finseth.com/craft/) は古い作品であり、単なるデータ構造以上のものを扱っており、Emacs スタイルのエディターを対象としています。しかし、概念は一般的に役に立ちます。
于 2009-07-20T20:28:22.450 に答える
3

単純なアプローチは行指向です-ファイルをchar/wchar_t配列/ベクトルの配列/ベクトルとして1行に1つずつ表します。行末は特殊なケースですが、挿入と削除は期待どおりに機能します。

私はそれから始めて、おそらく他のすべてが機能した後、行データ構造を長い行の挿入/削除をより効率的にサポートするものに置き換えます。

于 2008-09-30T18:26:58.617 に答える
3

ほとんどすべてのデータ構造を使用して、テキスト エディターを作成できます。200 万文字はかなり分厚い小説のタイピングに値する量であり、10 分の 1 秒未満で (単純な配列での挿入/削除の場合) 簡単に上下に移動できます。作成しないでくださいという人の言うことを聞かないでください。細部に至るまで正確に機能するものを手に入れることができます。

あまりにも多くの Web ブラウジングを行い、スクロールバーのつまみの上/下をクリックするのと同じようにページを上下に移動することに慣れた後、私は自分のものを書きました。通常のエディターで文字を入力したときに、スクロールバーのナビゲートを開始する前に戻るジャンプは、私にはあまりにも面倒だったので、私は自分で書いた.

書き換える場合 (現在のバージョンでは、改行文字を埋め込んだ各テキスト バッファーに Delphi Ansistring を使用しただけです)、各文字に整数または int64 を使用し、ブロックの開始/停止、カーソル位置、および行をエンコードします。マーカーを上位ビットに配置すると、挿入または削除するときにポインターを調整する必要がなくなります。

于 2008-10-01T07:07:21.020 に答える
2

プライマリ データ構造は、テキストを格納するものです。テキストを格納するために長いバッファーを使用するのではなく、おそらく行の配列が必要になるでしょう。行の中央に文字を挿入する方が、大きなバッファーの中央に文字を挿入するよりも高速だからです。

テキスト エディターが埋め込み書式をサポートする必要があるかどうかを判断する必要があります。たとえば、フォント、太字、下線などを使用する必要がある場合、データ構造には、テキスト内にフォーマット コードを埋め込む方法を含める必要があります。8 ビット文字の古き良き時代には、整数の上位 8 ビットを使用してフォーマット フラグを格納し、下位 8 ビットを使用して文字自体を格納することができました。

実際のコードは、使用している言語によって異なります。C# または C++ では、おそらく行に文字列の配列を使用するでしょう。C では、ヒープベースの文字配列の配列があります。

表示コードをテキスト処理コードからできるだけ分離します。コードの中心は、次のようなタイトなループになります。

while (editing) {
    GetCharacter();
    ProcessCharacter();
    UpdateDisplay();
}

より洗練されたエディタは、文字の取得/処理と表示の更新に別のスレッドを使用します。

于 2008-09-30T18:32:28.040 に答える
1

Scintillaのソースコードをチェックしましたか?

于 2008-09-30T20:53:04.567 に答える
1

これは本当にあなたのデザインに依存します。数年前、私は呪いを使って小さなエディターを書きました。各ノードが文字である二重リンクリストを使用しました(かなり無駄なデザインですが、フォーマットと画面の更新ルーチンが非常に簡単になります)。

私の友人が使用した他のデータ構造は(これは宿題のプロジェクトでした):1)各配列が線を表す配列のリンクリスト。2)2Dリンクリスト(その名前で構成されています)。これは文字のリンクリストでしたが、各文字は上下の文字にリンクされていました。3)リンクリストの配列

ただし、picoのようないくつかの単純なエディターのソースコードを調べて、それらが使用しているdsを確認することをお勧めします。

于 2008-09-30T18:30:46.407 に答える
-1

vimをチェックしてください。オープンソースです。それがあなたが望むものをどのように処理するかを見るためにそれをざっと見てください。

于 2008-09-30T18:25:17.747 に答える