简体   繁体   中英

C Program - Custom Text Editor Program

I am building a program for class that is supposed to function as a very basic text-based text editor. It has 9 commands that can be passed to it, each resulting in a different command and we are using a doubly linked list to manage the lines of text that can be appended, inserted, removed and navigated through. I have been given a few functions to work with, and although most of my questions I think are more conceptual, I'll provide these given functions as a basis of background information:

// Function: get_line
// Reads a line (of arbitrary length) from an input source (stdin or file)
// and returns a pointer to the array that stores the line read
//
char *get_line(FILE *f)
{
    int size = 80; // initial size of memory block allocated

    char *linePtr = malloc(size);  // allocate memory block

    if (linePtr != NULL) { // if allocation successful
        int c = EOF;

        // read a line of text and replace newline character
        // with a string terminator character
        int i = 0;
        while ((c = getc(f)) != '\n' && c != EOF) {
            linePtr[i++] = (char) c;
            if (i == size) {
                size *= 2;
                linePtr = realloc(linePtr, size);
            }
        }
        linePtr[i] = '\0';

        // if end-of-file before any characters were read,
        // release the whole buffer
        if (c == EOF && i == 0) {
            free(linePtr);
            linePtr = NULL;
        } else {
            // release unused portion of memory
            linePtr = realloc(linePtr, i+1);
        }
    }

    return linePtr;
}

My self-defined "append" function:

//
// Function: append_line
// Inserts a line after the current line (or node) in the linked-list
//
void append_line(char *t)
{
    line *new_stack;
    line *tmp;
    new_stack = malloc(sizeof(line));
    tmp = malloc(sizeof(line));

    if((new_stack == NULL) || (tmp == NULL)) {
        fprintf(stderr, "Insufficient memory to allocate. Closing application.\n");
            exit(1);
    }

    if(current_line == NULL) {
        if(head == NULL) {
            head = new_stack;
            current_line = new_stack;
            new_stack->prev = NULL;
            new_stack->next = NULL;
        }
    }
    else {
        tmp = current_line->next;
        current_line->next = new_stack->prev;
        new_stack->next = tmp;
        current_line = new_stack;
    }

    new_stack->text = t;
    free(tmp);
}

And this is my read_file function that doesn't really do anything yet, but I'm not exactly sure if I've got the right mind-set going into the creation of this function:

// Function: read_file
// Reads text from the specified file and calls append_line to insert lines
// into the linked-list. It returns the number of lines read.
//
int read_file(char *filename)
{
    char * temp, no_command;
    temp = strtok(filename, " ");
    while(temp != NULL) {
        no_command = temp;
        temp = strtok (NULL, " ");
    }
    /* By doing this --^, I hope it will set temp to the actual
    // file name after tokenization and completely ignore
    // the command that comes with filename */
    FILE *fin;
    int counter = 0;

    fin = fopen(no_command, "r");
    if(fin == NULL) {
        printf("You have entered a file that does not exist.");
        exit(0);
    }
    get_line(fin);
    fclose(fin);
}
  1. If I wanted to send get_line input entered by the user from another function, could I send get_line stdin for it to recognize user input typed on-screen? Or would I have to make use of some form of fgets to send it the information?

  2. If the user should be allowed to enter in multiple lines by separating them with the enter key (aka \\n ), and is expected to be allowed to press CTRL + D to continue with the function, how does one tell the application to make CTRL + D the EOF?

  3. My get_line function takes in an entire file, and outputs a line. I am instructed to make use of multiple calls of get_line to take files of multiple lines and send each line into their own respective stack entry. How do I tell the application, "Here's the same file, but I want you to NOW check the next line instead of the one you output previously"? I assume that once I figure this out, I can apply the same logic to input entered in on the fly by the user.

I have been instructed that the get_line function is complete, so I feel like in the places I would call get_line (such as in read_file ), I would need to control how much is sent to get_line at a time by making read_file read up to the point where a \\n is encountered, change it to an end-of-line symbol (aka '\\0' ) and send it to get_line , and then somehow have read_file continue after that point doing the same thing until EOF is reached. But I also feel like a lot of this functionality is within the get_line function as well... so I suppose I'm confused on the implementation of my given functions.

I'll probably have more questions in the future, but for now, I believe this initial question is long-winded enough. I'm hoping that figuring these things out, the rest of it will just click in place within my mind. Thank you for your time!

There are a couple of more errors in the append_line function, for example you use new_stack->prev before it's initialized.

Here comes my take on it:

void append_line(char *t)
{
    /* Allocate and clear (i.e. set all to 0) */
    line *new_stack = calloc(1, sizeof(line));

    if(current_line == NULL) {
        if(head == NULL) {
            head = current_line = new_stack;
        }
    }
    else {
        new_stack->next = current_line;
        new_stack->prev = current_line->prev;

        if (current_line->prev)
            current_line->prev->next = new_stack;
        else
            head = new_stack;  /* No previous node, means current_line is at head */

        current_line = new_stack;
    }

    new_stack->text = t;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM