程序对文字以行为单位进行编辑,功能有行的插入、行的删除、行的交换和进入下一页。要求用文本文件输入数据,并将修改好的数据保存到另一个文件中。因输入文件可能太大,不能将数据一次性全部输入,仅输入一部分。 首先要从文件中将数据读入内存,要以行为单位,而不能以每个字或每句话为单位。因此要定义一个结构体,存储一行的内容。而要使编辑方便,需要每行的编号,因此在结构体中要加入一个存储行号的变量。 但从文件中读数据不能一次全读完,因此定义一个活区的类,这个类里包含了行的数量和行的结构体变量。 接着将文件内容输出到显示器,将活区的内容分次输出。 下面就是对数据的处理了,每行的内容存储到结构体数组中,删除操作只需将后一个的把前一个覆盖,并将数组数量减一。 插入操作,将数组数量加一,从后向前到插入处,把前一个覆盖后一个。然后将要插入的内容写入插入处即可。
时间: 2024-02-18 15:03:47 浏览: 59
下面是一个基于C语言的简单行编辑程序示例代码,实现了文字以行为单位进行编辑,包括行的插入、行的删除、行的交换和进入下一页,同时支持从文件中读取数据、分次输出和保存修改后的数据到另一个文件中。
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LEN 1024
#define MAX_LINE_NUM 10000
// 定义行结构体
typedef struct {
int line_no;
char *line_text;
} line_t;
// 定义活区类
typedef struct {
int line_count;
line_t lines[MAX_LINE_NUM];
} buffer_t;
// 从文件中读取数据到活区
void load_file(buffer_t *buffer, const char *filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("Error: cannot open file %s\n", filename);
exit(1);
}
int line_no = 0;
char line_text[MAX_LINE_LEN];
while (fgets(line_text, MAX_LINE_LEN, fp) != NULL) {
line_no++;
line_t *line = &buffer->lines[buffer->line_count];
line->line_no = line_no;
line->line_text = strdup(line_text);
buffer->line_count++;
}
fclose(fp);
}
// 将活区的内容输出到显示器
void display(buffer_t *buffer, int start_line, int end_line) {
if (start_line < 1) {
start_line = 1;
}
if (end_line > buffer->line_count) {
end_line = buffer->line_count;
}
for (int i = start_line - 1; i < end_line; i++) {
printf("%d %s", buffer->lines[i].line_no, buffer->lines[i].line_text);
}
}
// 保存修改后的数据到文件
void save_file(buffer_t *buffer, const char *filename) {
FILE *fp = fopen(filename, "w");
if (fp == NULL) {
printf("Error: cannot open file %s\n", filename);
exit(1);
}
for (int i = 0; i < buffer->line_count; i++) {
fprintf(fp, "%s", buffer->lines[i].line_text);
}
fclose(fp);
}
// 删除指定行
void delete_line(buffer_t *buffer, int line_no) {
if (line_no < 1 || line_no > buffer->line_count) {
printf("Error: line number %d is out of range\n", line_no);
return;
}
for (int i = line_no - 1; i < buffer->line_count - 1; i++) {
buffer->lines[i] = buffer->lines[i + 1];
buffer->lines[i].line_no--;
}
buffer->line_count--;
}
// 插入一行到指定行之前
void insert_line(buffer_t *buffer, int line_no, const char *line_text) {
if (line_no < 1 || line_no > buffer->line_count + 1) {
printf("Error: line number %d is out of range\n", line_no);
return;
}
if (buffer->line_count == MAX_LINE_NUM) {
printf("Error: buffer is full, cannot insert new line\n");
return;
}
for (int i = buffer->line_count - 1; i >= line_no - 1; i--) {
buffer->lines[i + 1] = buffer->lines[i];
buffer->lines[i + 1].line_no++;
}
line_t *line = &buffer->lines[line_no - 1];
line->line_no = line_no;
line->line_text = strdup(line_text);
buffer->line_count++;
}
// 交换两行的位置
void swap_lines(buffer_t *buffer, int line_no1, int line_no2) {
if (line_no1 < 1 || line_no1 > buffer->line_count ||
line_no2 < 1 || line_no2 > buffer->line_count) {
printf("Error: line number is out of range\n");
return;
}
line_t tmp = buffer->lines[line_no1 - 1];
buffer->lines[line_no1 - 1] = buffer->lines[line_no2 - 1];
buffer->lines[line_no2 - 1] = tmp;
buffer->lines[line_no1 - 1].line_no = line_no1;
buffer->lines[line_no2 - 1].line_no = line_no2;
}
int main() {
buffer_t buffer = {0};
char input_line[MAX_LINE_LEN];
load_file(&buffer, "input.txt");
int start_line = 1;
int end_line = buffer.line_count < 10 ? buffer.line_count : 10;
while (1) {
display(&buffer, start_line, end_line);
printf("> ");
if (fgets(input_line, MAX_LINE_LEN, stdin) == NULL) {
break;
}
char cmd[10];
int arg1, arg2;
char arg3[MAX_LINE_LEN];
if (sscanf(input_line, "%s %d %d", cmd, &arg1, &arg2) == 3) {
if (strcmp(cmd, "d") == 0) {
for (int i = arg1; i <= arg2; i++) {
delete_line(&buffer, arg1);
}
} else if (strcmp(cmd, "s") == 0) {
swap_lines(&buffer, arg1, arg2);
}
} else if (sscanf(input_line, "%s %d %[^\n]", cmd, &arg1, arg3) == 3) {
if (strcmp(cmd, "i") == 0) {
insert_line(&buffer, arg1, arg3);
}
} else if (sscanf(input_line, "%s %d", cmd, &arg1) == 2) {
if (strcmp(cmd, "d") == 0) {
delete_line(&buffer, arg1);
} else if (strcmp(cmd, "s") == 0) {
printf("Error: please provide two line numbers to swap\n");
} else if (strcmp(cmd, "g") == 0) {
start_line = arg1;
end_line = start_line + 9;
if (end_line > buffer.line_count) {
end_line = buffer.line_count;
}
}
} else if (strcmp(input_line, "n\n") == 0) {
start_line = end_line + 1;
end_line += 10;
if (end_line > buffer.line_count) {
end_line = buffer.line_count;
}
} else if (strcmp(input_line, "p\n") == 0) {
start_line = start_line - 10;
if (start_line < 1) {
start_line = 1;
}
end_line = start_line + 9;
} else if (strcmp(input_line, "q\n") == 0) {
break;
}
}
save_file(&buffer, "output.txt");
return 0;
}
```
在这个示例程序中,我们定义了行结构体 `line_t`,其中包含了行号和行文本;定义了活区类 `buffer_t`,其中包含了行数和行结构体变量数组;实现了从文件中读取数据到活区、将活区内容输出到显示器、保存修改后的数据到文件、删除指定行、插入一行到指定行之前、交换两行的位置等一系列操作。
在主函数中,我们先调用 `load_file` 函数从文件中读取数据到活区,然后循环执行下列操作:
1. 调用 `display` 函数将活区的一部分内容输出到显示器。
2. 读取用户的输入命令,并根据命令执行相应的操作。
3. 如果用户输入了 `q` 命令,则退出循环,调用 `save_file` 函数将修改后的数据保存到文件。
其中,对于分次输出活区内容,我们使用 `start_line` 和 `end_line` 两个变量来控制输出的范围,每次输出 10 行,并根据用户输入的 `n` 和 `p` 命令来更新 `start_line` 和 `end_line` 的值。
对于其他操作,例如删除、插入、交换等,我们也根据用户输入的命令和参数来调用相应的函数执行操作。需要注意的是,为了方便用户,我们将删除和交换两行的操作合并到一个命令 `s` 中,用户可以指定要操作的行号范围。而对于插入一行的操作,由于要插入的文本可能包含空格,因此我们使用了 `%[^\n]` 格式控制符来读取一行中的所有字符,直到遇到换行符为止。
以上就是一个简单的行编辑程序的示例代码,可以根据实际需求进行修改和扩展。
阅读全文