0

I have a program that simulates a text editor. It lets users add lines of text to a list in whatever particular manner they choose depending on the command they send.

One of the functions lets users move backwards through the list to view their lines (there's another one that lets them move forward, but that one's not being problematic).

There's also functions to let users insert or append text. Insert has the line put in before the current line while append has it set after. One problem I'm having is the way insert puts in text.

User hits i for insert, puts text in via the standard input (stdin), and then hits CTRL + D (in a Linux environment) to simulate NULL and to return back to command mode. After that, if you go to navigate through the list, it seems to enter the last line at the top of the list and everything follows suit backwards. At one point, I had inserted 4 lines of text and it did an infinite loop of the last 2 lines and ruined the text file.

I believe it has to do with my logic in linking the lists, but I'm having a hard time visualizing them. Here are the problematic functions:

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

    new_line->text = t;

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

        if(current_line->prev == NULL)
            head = current_line;
    }
}

This must be terribly mucked up - the way it infinite loops the text sometimes and always puts the text in backwards. This is how I utilize the insert function:

else if(command[0] == 'i')
    {
        char * line;
        while((line = get_line(stdin)) != NULL)
            insert_line(line);
     }

get_line reads the text one line at a time and returns it until EOF is reached. I know the get_line function is working because my instructor wrote it for us to use.

//
// Function: previous_line
// Moves the current_line pointer to the previous node, if any, in the linked-list.
//
void previous_line(void)
{
    if(current_line == NULL)
        printf("Error: No Lines Exist.\n");
    else if(current_line->prev != NULL) {
        current_line = current_line->prev;
        printf("%s\n", current_line->text);
    }
    else
        printf("Error: Already beginning-of-line.\n");
}

This one is weird, when I append text in the middle of text, the next_line function works fine, but then when I run this to go back through the list, it shows nothing of what I've added.

2 Answers 2

1

Draw it on paper (a box for each line and some arrows for next and prev)

This bit has problems - should be fairly clear when you draw it.

new_line->prev = current_line->prev;
new_line->next = current_line;
current_line->next = new_line;
current_line = new_line;
Sign up to request clarification or add additional context in comments.

7 Comments

If I drew it out correctly, it would seem that I need to change the 3rd line of that to current_line->prev = new_line so that what current_line points to is the new_line next. So then I thought to myself, "If I change the 4th line to current_line = new_line->next, it would alleviate the problem where it was putting the lines in backwards since technically this way it inserts each new line before the other. But then... I changed that and then at the end of the insert, it points to the wrong one, as it should be pointing to the lastly added line AND nothing was being added :/
Meaning that when I try to write the list to a file, it only sees the original content, not any of the newly inserted lines.
If you start with i1 <=> C <=> i2, after I run the above 4 lines, i2 is in a funny state - nothing points to it, but it's prev is the old current_line. (C = current_line)
With this being an insert function though, shouldn't we not have to worry about what's after the current line assuming the link is properly established in the first place? Since the new line is being inserted in-between the previous line and the current line, I thought that what's after current line is irrelevant because nothing there is changing and that you need to establish the double link between the current line's previous and the new line's next?
What's weird to me right now is that I'm certain the information is at least half there, because when I go backwards on the list, I can see the newly added items, but when I go forward, I do not. Also when I try to write the data out, it does not add the new lines. Why would current line's next be affected from a line insert when we're only making changes to its previous? Maybe I'm just not understanding the way these doubly linked lists work.
|
0

If you are trying to append the newline to the text file, you should be doing

new_line->prev = current_line;
current_line->next = new_line;

current_line = new_line;

3 Comments

My append line is functioning - the insert line is what I have here and it should be adding the new line before the current line's position.
I dint get you. What does current_line store then? Is it like insert between 2 lines?
this should help: struct line previous = current_line->prev; previous->next = new_line; new_line->prev = previous; new_line->next = current_line; current_line->prev = new_line; current_line = new_line;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.