首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

資料結構教學:字串操作於文本編輯器的實際應用

     編輯:Oracle 資料庫基礎

教學目標與重點

本課程旨在掌握文本編輯的基本原理與方法,重點實作簡單的行編輯程式,難點在於字串的儲存管理與高效操作。透過堆分配儲存表示,實現動態記憶體管理,支援大型文本的編輯需求。

一、字串的堆分配儲存表示

採用堆動態分配方式儲存字串,結構包含字元指標與長度資訊,支援字串的動態增刪修改:

typedef struct {
    char *ch;     // 字串基址
    int length;   // 字串長度
} HString;

此方式避免了靜態陣列的固定長度限制,適合文本編輯器頻繁插入刪除的場景。

二、文本編輯基本原理

文本的邏輯結構

對使用者而言,文本由頁、行、字元組成;對程式而言,可視為一個長字串(文本串),頁是其子串,行是頁的子串。為簡化實作,通常將文本簡化為行的集合。

編輯核心操作

所有文本編輯器的基本操作一致,包含三大核心:

  • 字串查找:定位目標內容
  • 字串插入:在指定位置新增字元
  • 字串刪除:移除指定範圍字元

記憶體中的儲存映像

以 C 程式碼為例,原始碼在記憶體中以連續字元形式儲存,換行符 \n 分隔行:

main() { \n
float a,b,max; \n
scanf("%f,%f",&a,&b); \n
if (a>b) max=a; \n
else max=b; \n
} \n

編輯時需維護頁指標、行指標、字元指標,並建立頁表、行表以利快速定位。

三、簡單行編輯程式實作

以下為完整的行編輯器原始碼,採用順序表管理行結構,支援檔案讀寫、游標移動、字元插入刪除、行新增刪除等功能:

核心資料結構

struct line {
    int charnum;    // 行字元數
    char *base;     // 行內容指標
};
typedef struct line SequListElemType;
#include "sequlist.h"  // 順序表操作介面

#define MAXLINES 1000
SequList *Document;   // 文檔行順序表

關鍵功能函式

1. 行編輯 editline()

讀取指定行內容至緩衝區,呼叫 getstring() 進行互動編輯,完成後更新順序表:

void editline(int curline, int maxcolnum) {
    char s[2000];
    strcpy(s, Document->elem[curline].base);
    getstring(editwinx, editwiny+curline-curscrtopline, s, maxcolnum);
    free(Document->elem[curline].base);
    Document->elem[curline].base = (char *)malloc(strlen(s)+1);
    strcpy(Document->elem[curline].base, s);
}

2. 文檔顯示 printdoc()

在編輯視窗中顯示指定範圍的行內容:

void printdoc(int startfileline, int startscrline) {
    int i = startscrline, j = startfileline;
    while (i <= editwinlines && i < Document->length) {
        clearscrline(editwinx, editwiny+i, 78);
        putsxy(editwinx, editwiny+i++, Document->elem[j++-1].base);
    }
    while (i <= editwinlines) clearscrline(editwinx, editwiny+i++, 78);
}

3. 字元插入與刪除

在字串指定位置插入/刪除字元,需移動後續字元:

void insertchar(char *s, char c, int pos) {
    for (int i = strlen(s)+1; i > pos; i--) s[i] = s[i-1];
    s[pos] = c;
}

void deletechar(char *s, int pos) {
    for (int i = pos; i <= strlen(s); i++) s[i] = s[i+1];
}

4. 互動式字串輸入 getstring()

處理鍵盤輸入,支援游標移動、Home/End、Backspace/Delete、插入字元等編輯鍵:

void getstring(int x, int y, char *s, int num) {
    int curpos = 0, thisover = 0, k;
    while (!thisover) {
        if (k = bioskey(1)) {
            switch(k) {
                case KEYLeft:  if (curpos) curpos--; break;
                case KEYRight: if (curpos < num) curpos++; break;
                case KEYBackspace:
                    if (curpos) { deletechar(s, curpos-1); curpos--; }
                    break;
                case KEYDelete:
                    if (curpos < strlen(s)) deletechar(s, curpos);
                    break;
                case KEYReturn: thisover = 1; break;
                case KEYEsc: return;
                default:
                    char c = ascii(k);
                    if (c && strlen(s) < num) {
                        insertchar(s, c, curpos++);
                    }
            }
            // 重繪行內容與游標位置
            clearscrline(x, y, num);
            putsxy(x, y, s);
            gotoxy(x+curpos, y);
        }
    }
}

5. 檔案操作

支援開啟、讀取、儲存、關閉檔案,使用順序表管理所有行:


void readdoc(FILE *fp) {
    char s[20000], *newline;
    struct line curline;
    int linenum = 0;
    while (!feof(fp)) {
        getline(fp, s);
        linenum++;
        newline = (char *)malloc(strlen(s)+1);
        strcpy(newline, s);
        curline.base = newline;
        curline.charnum = strlen(newline);
        SequListInsert(Document, linenum, curline);
    }
}

主程式流程

初始化選單系統、建立空文檔、進入事件迴圈處理鍵盤與選單命令:


int main() {
    // 初始化選單、視窗、順序表
    SequListInit(&Document, MAXLINES);
    insertnewline(1);  // 插入第一空行
    
    while (!mainover) {
        if (key = bioskey(1)) {
            // 處理功能鍵:上下左右、Enter、Backspace、Ctrl+Y刪除行等
            // 處理選單命令:開啟檔案、儲存、退出
        }
    }
    closedoc(curfile);
}

實作總結

此行編輯器展示了字串操作在實際應用中的核心邏輯:以順序表管理行集合,每行採用動態字串儲存,透過字元級的插入刪除演算法實現編輯功能。雖介面基於字元模式,但完整體現了文本編輯器的資料結構設計與操作原理,為理解現代編輯器架構奠定基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved