-
Simple Editor
Hi there,
I'm having a lot of trouble trying to write an apparently "simple" editor. What do you make of my code? It's already late to hand in.
Code:
#include <stdio.h>
#include <conio.h>
#include <string.h>
char text[23][80];
int main() {
int i=0, num;
char c[80];
char temp[80];
FILE *g;
printf("Please enter the file name:\n");
gets(c);
g = fopen(c, "r");
if(g == NULL) {
printf("Problem! The file did not open sucessfully.");
exit(0);
}
while(fgets (text[i], 80, g) !=NULL) {
i++;
}
fclose(g);
system("cls");
for(i=0; i<23; i++) {
printf("%s", text[i]);
}
printf("Command:");
fgets(temp, sizeof(temp), stdin);
sscanf(temp, "%c %d", c, &num);
while(strcmp(temp, "Q") !=0) {
if(strcmp(temp, "R") ==0) {
fgets(text[num],80,stdin);
}
if(strcmp(temp, "D") ==0) {
for(i=21; i<num; i++) {
strcpy(text[i], text[i+1]);
}
}
if(strcmp(temp, "I") ==0) {
for(i=22; i>num; i--) {
strcpy(text[i], text[i-1]);
}
}
if(strcmp(temp, "S") ==0) {
for(i=0; i<23; i++) {
fprintf(g, text[i]);
}
}
}
}
-
Your system("cls"); only works in Windows and DOS. Instead, you could use CSI codes (ANSI escape codes). The CSI in the list is simply the string "\033[", so to for example clear the screen you can use
Code:
printf("\033[H\033[2J"); /* Move cursor to upper left corner, then clear the screen. */
For a text-mode editor, the ncurses library provides a lot of useful features, like automatic screen (terminal) size detection and so on. On Windows, pdcurses or win32a should do fine.
As to the data structures, I'd define a dynamic string type (with a end-of-line type flag). Perhaps
Code:
struct line {
size_t size; /* Bytes allocated */
size_t used; /* Bytes used */
unsigned char newline;
unsigned char data[];
};
struct document {
size_t size; /* Lines allocated */
size_t used; /* Lines used */
struct line *line[];
};
struct document *document_load(const char *const filename);
int document_save(const struct document *const doc, const char *const filename);
int document_insert(struct document *const doc, const size_t before_line, struct line *const line);
int document_delete(struct document *const doc, const size_t line);
int line_free(struct line *const line);
struct line *line_new(const unsigned char *const from, const size_t length);
struct line *line_grow(struct line *const line, const size_t minimum);
struct line *line_copy(const struct line *const line);
When inserting or deleting lines, only the pointers need to be updated. When appending a line, the struct line can be reallocated when necessary, so it can be grown longer. The line_ helper functions would allow you to manipulate the contents of a line as you wish.
The reason for the newline constant for each line is that if you include it in the string itself, it will make your line editing and display functions overly complicated. Also, if instead of an actual character it is a constant, you can support different newline conventions without issues. (One of my pet peeves is how many editors mangle and get confused about newline conventions. I'd want an editor that supports NUL ('\0'), LF ('\n'), CR ('\r'), LF CR ("\r\n"), and CR LF ("\n\r") without me having to do anything about it.)
It would be even better to use wchar_t data[]; in the struct line, so each element in that array would correspond to a glyph (character) in the user's locale. (For example, € takes nowadays three chars, if you are using the UTF-8 character set as you should. "But I don't want to bother" is a poor excuse for mangling peoples names, for example.)
Is there anything specific you want to ask?
-
I can only assume that Nominal (more accurately, Actual) Animal's post is a joke. Just ignore it.
What are the specs for your assignment?
What is your simple editor supposed to do?
-
Here is a copy of the task sheet.
Write a simple editor.
The editor should first ask the user for the name of a file to edit.
You may assume that the file already exists.
Files will be restricted to exactly 23 lines of text.
The editor should display the text in the file starting at the top of the screen.
The 24'th line is used by the user to give commands to the editor. The prompt should be Command:
The only commands that are available are:
D number which will delete the line with that number. All lines after that one will move up one.
The new 23rd line at the bottom will be empty.
I number Will insert the text typed on the 25'th line before the line with that number
All lines will move down one to accommodate the new line.
The old 23'rd line will be discarded.
R number Will replace, with the text typed on the 25'th line, the line with that number
S Will save away the changes, by writing the text back to disk.
Q Will quit the program
eg
Command: I 6
this new line will be placed between line 5 and line 6 of the file
After each command the screen should be cleared using the function system("cls");.
The text should then be displayed again.
Line numbers given by the user will, in true computer science style, start from 0 and go to 22.