lite,。
Aims
This exercise aims to give you practice in dealing with dynamic data structures, specifically linked lists. The goal is to complete the implementation of a medium-sized program that can do simple text editing.
Background
The assignment is to write a simple line-based text editor called lite (which stands for line text editor). The editor lite stores lines of text in a linked list: each line of text is stored in a node of the linked list. If there are n lines of text, they are numbered from 1 to n for the user. At every point in time the editor has a current line number (which is an index between 1 and n). When lite is started up, the current line number is 1. The line-based commands allow the user to print lines, to delete the current line, to insert and append lines before or after the current line and to go-to a particular line. There are also file-oriented commands that enable the user to save changes and quit the editor, to force an exit or to change the name of the file. Note that lite does not contain a search command or contain any way of changing text apart from deleting ‘old’ lines and appending and inserting new lines.
The main objectives of this assignment are:
- use and manipulate dynamic data structures (like linked lists) to solve a complex problem
- learn how to implement a linked list data structure and functions for maintaining the data structure
- gain experience with implementing a more comprehensive functionality for editing text files
- write a properly documented C program that adheres to the course Style Guide
NOTE: You should think carefully about the appropriate data structures and algorithms to use in your program. Before starting to write any code it is important that you fully understand the problem and determine the data structures that you will require and the algorithms to use. It is highly recommended that you start coding only after you have spent some time on these considerations. In particular, you must not make any assumptions about the number of lines in a text file; this means that you must use dynamically-allocated linked-list data structure to manage a text file.
What the editor should do
A file name is the only optional argument to the lite command. So you execute lite either by:
prompt$ ./lite
or
prompt$ ./lite filename
where filename is a file name that may or may not exist. If there are more arguments, then the usage error message from lite is:
Usage: ./lite [filename]
The square brackets indicate that filename is optional.
Examples of Use
When lite is waiting for user input it uses the prompt ‘?’. When text is printed, each line is preceded by its line number. The current line number is indicated by an arrow.
Example 2
The user can start up the editor without a file name, print the help command and then quit.
prompt$ ./lite ? h Commands are (in upper or lower case): q: quit s: save x: force exit f lt;filenamegt;: the file is called lt;filenamegt; h: print this help message d: delete current line a: append after current line, terminated by apos;.apos; i: insert before current line, terminated by apos;.apos; p: print all lines .: print current line +: increment line and print lt;returngt;: same as apos;+apos; -: decrement line and print number: make apos;numberapos; the current line ? q bye prompt$
Example 2
I love a sunburnt country, A land of sweeping plains, Of ragged mountain ranges, Of droughts and flooding rains. I love her far horizons, I love her jewel-sea, Her beauty and her terror - The wide brown land for me!
then an example of an edit session that involves the user
- a. opening the file Mackellar.txt,
- b. printing its contents by entering the command p,
- c. moving to the 8th line in the file (this is the last line) by entering 8,
- d. appending 4 lines (consisting of a blank line, the name of the poem, the author and her year of birth and death)
- notice the text is terminated by a line containing the symbol ‘.’ only (just like UNIX’s ed)
- the current line number after an insertion is the last line to be entered
- e. entering an incorrect command v,
- f. printing the contents again by entering p,
- g. saving the text by entering s, and finally
- h. quitting the editor by entering q
is shown below:
prompt$ ./lite Mackellar.txt Existing file quot;Mackellar.txtquot; ? p ---gt; 1: I love a sunburnt country, Line 2: A land of sweeping plains, Line 3: Of ragged mountain ranges, Line 4: Of droughts and flooding rains. Line 5: I love her far horizons, Line 6: I love her jewel-sea, Line 7: Her beauty and her terror - Line 8: The wide brown land for me! ? 8 ---gt; 8: The wide brown land for me! ? a quot;My Countryquot; Poem by Dorothea Mackellar (1885--1968) . ? v Unknown command: ignoring ? p Line 1: I love a sunburnt country, Line 2: A land of sweeping plains, Line 3: Of ragged mountain ranges, Line 4: Of droughts and flooding rains. Line 5: I love her far horizons, Line 6: I love her jewel-sea, Line 7: Her beauty and her terror - Line 8: The wide brown land for me! Line 9: Line 10: quot;My Countryquot; Line 11: Poem by Dorothea Mackellar ---gt; 12: (1885--1968) ? s Saving file quot;Mackellar.txtquot; ? q bye prompt$
Example 3
In the next example, the user steps down an existing C program to a particular line, deletes the line and inserts a new line.
prompt$ ./lite hw.c Existing file quot;hw.cquot; ? p ---gt; 1: #include lt;stdio.hgt; Line 2: #define NUMBER 10 Line 3: int main(void) { Line 4: int i; Line 5: for (i=0; ilt;NUMBER; i++) { Line 6: printf(quot;hello, world!\nquot;); Line 7: } Line 8: return 0; Line 9: } ? + ---gt; 2: #define NUMBER 10 ? + ---gt; 3: int main(void) { ? + ---gt; 4: int i; ? + 5: for (i=0; ilt;NUMBER; i++) { ? + 6: printf(quot;goodbye, world!\nquot;); ? s Saving file quot;hw.cquot; ? q bye prompt$
Note that it would have been faster, of course, to have typed in the line number, 6, rather than step down line by line.
Approach
Do not try to write the whole program at once. Break the development into pieces of functionality and implement the easiest first:
Stage 1 – Reading Text
- Write a program that reads lines of text from stdin and creates a linked list in which each node contains a single line.
- You will need a function that prints all the nodes in a linked list to check that the read was successful. You are allowed to copy chunks of code from the list.c library from lectures, if you find it helpfu㸠੦†⁹⁵†⁵†㱥㵩≳≵㸠൭ੵ⁴††⁴†⁷㱩㹡㰠㴠≩≡㹴㱥†㵥∮∠㸠㰍⼊㸼 㱬†㵩∾≴㹨㱲⽡㸠⍯ㅭ㈠㍡㬠㱦⽩㹷㱨⼠㹴㱨㵴≨≬㹥††㱧†㵥∠∠㹬㰼⼯㸊‼⨯㬊‼″†‽•㱓㵡≳≧㹡⽴⽩•′㱡⽳㹡㱶⽩㹮㱧⼳㸾㰍‾㴠∼≨㹡†㱴㴠≴≴㸠㰠⽣㹮⨠㭫㱥⽹㹤㰺†⼠㸠㰠㴠∠≩㸾⍰ㄠ㉴㕯㬠⁰䱲㬠㱴⽨㹭㱰⁴⽥㸠㱣⽯㹮൴ੳ††⁴†㱥⽤㹩൳ੴ†
⁴†㱬⽳㹨ਠ⁵㱴⽩㹵ഠ㱲⽯㹲൬੩㱥⽲㸍㰊⼠㸠ഠਠ㰠㸠☼㬠㱴⽯㹰൲੩㱮㸠†⁰‾††⁴†⁵㰠⽮㹥d to write a function to free the linked-list nodes)
- if the command is not one of the above, an appropriate message should be printed and the program should wait for the next command
- Now add the ‘move around’ commands to the program:
- an integer to go to a particular node in the linked list and print the corresponding line
- this raises the issue of the current line number, which is central to the workings of the editor
- + and - to print the line before and after the current line
- it should be possible to enter any number of + and - to step through the linked list
- address the problem of what happens to the current line when you reach the start and end of the linked list
Stage 3 – Editing
- Now add the delete and insert/append operations:
- do d first; remember to free the linked-list node when the line of text is deleted
- be mindful of what happens to the current line when you have inserted/appended or deleted lines
- Add file I/O to the program, which involve the s, q and f commands:
- the f command is tricky as it requires a filename argument
- the s command will write the complete linked list to a file
- the q command requires the program to know whether the lines of text have changed or not
Hints
You may use fixed-length arrays to read a line of text from stdin:
1
|
#define LINELENGTH 1000
|
and to read a filename or an editor command:
1 2
|
#define FNAMELENGTH 100 #define CMDLENGTH 102
|
However, you should use the heap to store the lines in the linked list. The nodes in the linked list, each storing one line of text, may be quite simple: