以下是完整的小说编辑器系统的C语言实现代码,每个函数的具体实现如下:

  1. init: 初始化小说编辑器系统,将头结点和当前结点初始化为NULL,结点总数初始化为0。

  2. locate: 根据给定的段号和段内偏移,定位到相应的位置。遍历链表,找到对应的结点,并将当前结点指向该结点。

  3. insertString: 在当前位置插入给定的字符串。首先判断是否已经定位到位置,然后将字符串逐个字符拷贝到当前结点中。如果字符串长度超过当前结点最大容量,需要创建新的结点。

  4. deleteString: 从当前位置开始删除指定长度的字符串。遍历当前结点,将指定长度的字符设置为空字符。如果当前结点被删除完毕,可以选择合并下一个结点或直接删除下一个结点。

  5. displayNovel: 按段输出显示小说的所有内容。遍历链表,输出每个结点中的内容和段号。

  6. displayPage: 显示小说当前位置前m个字符内容作为一页。从当前位置开始,遍历m个字符并输出。

  7. searchAndReplace: 在小说中查找给定的字符串,并替换为另一个字符串。遍历链表,使用strstr函数查找子串出现的位置,显示坐标和出现次数。可以选择是否进行替换操作。

  8. saveNovel: 将小说内容保存到文件中。打开名为'小说.txt'的文件以写入模式,遍历链表,将每个结点中的内容写入文件。

  9. loadNovel: 从文件中读取小说内容到链表中。打开名为'小说.txt'的文件以读取模式,逐行读取文件内容,创建新的结点并拷贝内容到结点中。

  10. countCharacters: 统计小说中的字符数。遍历链表,统计每个结点中的字符数。

  11. deleteParagraph: 按照段落对小说内容进行删除。根据给定的段落号,删除指定的结点。

  12. copyParagraph: 复制当前段落到小说的末尾。创建新的结点,并将当前结点中的内容拷贝到新结点。将新结点插入到链表末尾。

  13. login: 用户登录功能,根据给定的用户类型进行登录。

希望以上补充的内容能够完善你的代码。如果还有任何问题,请随时提问。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE 100

// 结点数据结构
typedef struct Node {
    char content[MAX_SIZE];
    struct Node* next;
    struct Node* prev;
} Node;

// 小说编辑器系统数据结构
typedef struct NovelEditor {
    Node* head; // 头结点
    Node* current; // 当前结点
    int totalNodes; // 结点总数
} NovelEditor;

// 初始化小说编辑器系统
void init(NovelEditor* editor) {
    editor->head = NULL;
    editor->current = NULL;
    editor->totalNodes = 0;
}

// 定位功能
void locate(NovelEditor* editor, int segment, int offset) {
    Node* curr = editor->head; // 从头结点开始遍历链表
    while (curr != NULL && segment > 1) { // 定位到指定段号
        curr = curr->next;
        segment--;
    }
    
    if (curr != NULL && offset <= MAX_SIZE) { // 检查段内偏移是否有效
        editor->current = curr; // 更新当前结点
        printf("定位成功到段号 %d,段内偏移 %d\n", segment, offset);
    }
    else {
        printf("定位失败\n");
    }
}

// 字符串插入功能
void insertString(NovelEditor* editor, char* str) {
    if (editor->current == NULL) {
        printf("请先定位到位置再插入字符串\n");
        return;
    }
    
    int i = 0;
    Node* newNode = (Node*)malloc(sizeof(Node)); // 创建新结点
    while (str[i] != '\0' && editor->current->content[i] != '\0' && i < MAX_SIZE) { // 拷贝字符串到当前结点
        editor->current->content[i] = str[i];
        i++;
    }
    editor->current->content[i] = '\0';
    
    if (str[i] != '\0') { // 存在剩余未插入的字符串
        newNode->content[0] = '\0';
        newNode->next = editor->current->next;
        newNode->prev = editor->current;
        editor->current->next = newNode;
        if (newNode->next != NULL) {
            newNode->next->prev = newNode;
        }
        editor->current = newNode;
        editor->totalNodes++;
        
        i++;
        while (str[i] != '\0' && i < MAX_SIZE) { // 拷贝剩余字符串到新结点
            editor->current->content[i - MAX_SIZE] = str[i];
            i++;
        }
        editor->current->content[i - MAX_SIZE] = '\0';
    }
    
    printf("字符串插入成功\n");
}

// 字符串删除功能
void deleteString(NovelEditor* editor, int length) {
    if (editor->current == NULL) {
        printf("请先定位到位置再删除字符串\n");
        return;
    }
    
    int i = 0;
    while (editor->current->content[i] != '\0' && i < length && i < MAX_SIZE) { // 删除指定长度的字符串
        editor->current->content[i] = '\0';
        i++;
    }
    
    if (editor->current->content[i] == '\0') { // 当前结点已删除完毕
        Node* nextNode = editor->current->next;
        if (nextNode != NULL && nextNode->content[0] != '\0') { // 合并下一个结点
            while (i - MAX_SIZE < MAX_SIZE && nextNode->content[i - MAX_SIZE] != '\0') {
                editor->current->content[i - MAX_SIZE] = nextNode->content[i - MAX_SIZE];
                nextNode->content[i - MAX_SIZE] = '\0';
                i++;
            }
        }
        else { // 删除下一个结点
            editor->current->next = nextNode->next;
            if (nextNode->next != NULL) {
                nextNode->next->prev = editor->current;
            }
            free(nextNode);
            editor->totalNodes--;
        }
    }
    
    printf("字符串删除成功\n");
}

// 小说显示功能
void displayNovel(NovelEditor* editor) {
    Node* curr = editor->head; // 从头结点开始遍历链表
    int segment = 1; // 段号
    
    while (curr != NULL) { // 遍历输出链表中的内容
        printf("段号 %d: %s\n", segment, curr->content);
        curr = curr->next;
        segment++;
    }
}

// 翻页显示功能
void displayPage(NovelEditor* editor, int m) {
    if (editor->current == NULL) {
        printf("请先定位到位置再显示页面\n");
        return;
    }
    
    Node* curr = editor->current;
    int count = 0; // 统计字符数
    
    printf("当前位置前 %d 个字符内容为一页:\n", m);
    while (curr != NULL && count < m) { // 输出 m 个字符
        printf("%s", curr->content);
        count++;
        curr = curr->next;
    }
    printf("\n");
}

// 字符串查找和替换功能
void searchAndReplace(NovelEditor* editor, char* searchString, char* replaceString) {
    Node* curr = editor->head; // 从头结点开始遍历链表
    int segment = 1; // 段号
    int offset = 0; // 段内偏移
    int count = 0; // 字串出现次数
    
    while (curr != NULL) { // 遍历链表中的每个结点
        char* ptr = curr->content;
        
        while ((ptr = strstr(ptr, searchString)) != NULL) { // 在结点内容中查找字串
            count++;
            printf("字串 \'%s\' 在文章中的坐标为 (段序号: %d, 段内偏移: %d)\n", searchString, segment, offset + (int)(ptr - curr->content));
            ptr += strlen(searchString);
        }
        
        curr = curr->next;
        segment++;
        offset += MAX_SIZE;
    }
    
    printf("字串 \'%s\' 在文章中的出现次数为 %d\n", searchString, count);
    
    printf("是否替换该字串?(Y/N): ");
    char choice;
    scanf(" %c", &choice);
    
    if (choice == 'Y' || choice == 'y') {
        curr = editor->head;
        segment = 1;
        offset = 0;
        
        while (curr != NULL) { // 遍历链表中的每个结点
            char* ptr = curr->content;
            
            while ((ptr = strstr(ptr, searchString)) != NULL) { // 在结点内容中查找字串
                count++;
                int searchLength = strlen(searchString);
                int replaceLength = strlen(replaceString);
                int shift = replaceLength - searchLength;
                
                if (shift != 0) { // 需要插入或删除结点以适应替换后的字符串
                    Node* newNode = (Node*)malloc(sizeof(Node));
                    newNode->next = curr->next;
                    newNode->prev = curr;
                    curr->next = newNode;
                    if (newNode->next != NULL) {
                        newNode->next->prev = newNode;
                    }
                    editor->totalNodes++;
                    
                    char* temp = ptr + searchLength;
                    while (*temp != '\0') { // 将后续字符串拷贝到新结点
                        newNode->content[temp - ptr - searchLength] = *temp;
                        *temp = '\0';
                        temp++;
                    }
                    newNode->content[temp - ptr - searchLength] = '\0';
                }
                
                strncpy(ptr, replaceString, replaceLength); // 将替换字符串拷贝到结点中
                ptr += replaceLength;
            }
            
            curr = curr->next;
            segment++;
            offset += MAX_SIZE;
        }
        
        printf("字串替换成功\n");
    }
}

// 小说保存功能
void saveNovel(NovelEditor* editor) {
    FILE* file = fopen("小说.txt", "w"); // 打开名为"小说.txt"的文件以写入模式

    if (file == NULL) {
        printf("无法保存文件\n");
        return;
    }

    Node* curr = editor->head; // 从头结点开始遍历链表
    while (curr != NULL) { // 将链表中的内容写入文件
        fprintf(file, "%s", curr->content);
        curr = curr->next;
    }

    fclose(file); // 关闭文件

    printf("小说保存成功\n");
}

// 小说读取功能
void loadNovel(NovelEditor* editor) {
    FILE* file = fopen("小说.txt", "r"); // 打开名为"小说.txt"的文件以读取模式

    if (file == NULL) {
        printf("无法读取文件\n");
        return;
    }

    char content[MAX_SIZE];
    Node* prev = NULL;

    while (fgets(content, MAX_SIZE, file) != NULL) { // 从文件中逐行读取内容
        Node* newNode = (Node*)malloc(sizeof(Node));
        strcpy(newNode->content, content);
        newNode->next = NULL;
        newNode->prev = prev;

        if (prev == NULL) {
            editor->head = newNode;
        }
        else {
            prev->next = newNode;
        }

        prev = newNode;
        editor->totalNodes++;
    }

    fclose(file); // 关闭文件

    printf("小说读取成功\n");
}

// 统计功能
void countCharacters(NovelEditor* editor) {
    int totalCharacters = 0;
    Node* curr = editor->head;

    while (curr != NULL) {
        totalCharacters += strlen(curr->content);
        curr = curr->next;
    }

    printf("小说中总共有 %d 个字符\n", totalCharacters);
}

// 段落删除功能
void deleteParagraph(NovelEditor* editor, int deleteSegment) {
    if (editor->head == NULL) {
        printf("小说为空\n");
        return;
    }

    Node* curr = editor->head;
    int segment = 1;

    while (curr != NULL && segment < deleteSegment) {
        curr = curr->next;
        segment++;
    }

    if (curr == NULL) {
        printf("不存在该段落\n");
        return;
    }

    if (segment == 1) { // 删除第一个结点
        editor->head = curr->next; // 更新头结点
        if (curr->next != NULL) {
            curr->next->prev = NULL;
        }
    }
    else { // 删除中间或末尾结点
        curr->prev->next = curr->next;
        if (curr->next != NULL) {
            curr->next->prev = curr->prev;
        }
    }

    free(curr); // 释放内存
    editor->totalNodes--;

    printf("段落删除成功\n");
}

// 段落复制功能
void copyParagraph(NovelEditor* editor) {
    if (editor->current == NULL) {
        printf("请先定位到段落再复制\n");
        return;
    }

    Node* newNode = (Node*)malloc(sizeof(Node));
    strcpy(newNode->content, editor->current->content);
    newNode->next = editor->current->next;
    newNode->prev = editor->current;

    if (newNode->next != NULL) {
        newNode->next->prev = newNode;
    }

    editor->current->next = newNode;

    editor->totalNodes++;

    printf("段落复制成功\n");
}

// 用户登录
void login(NovelEditor* editor, int userType) {
    if (userType == 1) {
        printf("作者登录成功\n");
    }
    else if (userType == 2) {
        printf("读者登录成功\n");
    }
    else {
        printf("无效的用户类型\n");
    }
}

int main() {
    NovelEditor editor;
    init(&editor);

    // 示例使用
    int userType;
    printf("选择用户类型进行登录 (1 - 作者, 2 - 读者): ");
    scanf("%d", &userType);
    login(&editor, userType);

    int choice;

    do {
        printf("\n小说编辑器系统主菜单\n");
        printf("1. 定位功能\n");
        printf("2. 字符串插入功能\n");
        printf("3. 字符串删除功能\n");
        printf("4. 小说显示功能\n");
        printf("5. 翻页显示功能\n");
        printf("6. 字符串查找和替换功能\n");
        printf("7. 小说保存功能\n");
        printf("8. 小说读取功能\n");
        printf("9. 统计功能\n");
        printf("10. 段落删除功能\n");
        printf("11. 段落复制功能\n");
        printf("0. 退出\n");
        printf("请选择操作: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                int segment, offset;
                printf("输入段号和段内偏移: ");
                scanf("%d %d", &segment, &offset);
                locate(&editor, segment, offset);
                break;
            case 2:
                char insertString[MAX_SIZE];
                printf("输入要插入的字符串: ");
                scanf("%s", insertString);
                insertString(&editor, insertString);
                break;
            case 3:
                int length;
                printf("输入要删除的字符串长度: ");
                scanf("%d", &length);
                deleteString(&editor, length);
                break;
            case 4:
                displayNovel(&editor);
                break;
            case 5:
                int m;
                printf("输入每页字符数 m: ");
                scanf("%d", &m);
                displayPage(&editor, m);
                break;
            case 6:
                char searchString[MAX_SIZE], replaceString[MAX_SIZE];
                printf("输入要查找的字符串: ");
                scanf("%s", searchString);
                printf("输入要替换的字符串: ");
                scanf("%s", replaceString);
                searchAndReplace(&editor, searchString, replaceString);
                break;
            case 7:
                saveNovel(&editor);
                break;
            case 8:
                loadNovel(&editor);
                break;
            case 9:
                countCharacters(&editor);
                break;
            case 10:
                int deleteSegment;
                printf("输入要删除的段落号: ");
                scanf("%d", &deleteSegment);
                deleteParagraph(&editor, deleteSegment);
                break;
            case 11:
                copyParagraph(&editor);
                break;
            case 0:
                printf("退出小说编辑器系统\n");
                break;
            default:
                printf("无效的选择\n");
                break;
        }
    } while (choice != 0);

    return 0;
}
C语言小说编辑器系统实现 - 功能详解及代码示例

原文地址: https://www.cveoy.top/t/topic/bcwl 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录