Home > front end >  Why is my program outputting garbage characters? (Language: C)
Why is my program outputting garbage characters? (Language: C)

Time:12-25

I have the following problem:

for an assignment I am supposed to read a txt file line by line, make every line an element in a linked list and then print them out in the correct order.

If I understand the debugger correctly, I am already achieving this but my output looks like a mess. I suspected the nulltermination to be wrong, but that doesn't seem to be the case here (see further down). Picture of the output

For readability I haven't written out the whole code, just what I think is the important part of the program.

#include <stdlib.h>
#include <stdio.h>

typedef struct node{
    struct node *p;
    char* string;
}node;

char *readline(FILE *stream)
//returns reference to string, returns NULL if EOF is reached before any char was read.
//If a line is EOF terminated it will return the string to the point where EOF was reached.
{
    char *string = malloc(sizeof(char));
    char c;
    int len = 0;
    if((c = getc(stream)) == EOF) return NULL;
    do{
        *(string   len) = c;
        len  ;
        realloc(string, (sizeof(char)*(len) 1));
        if(c == '\n') break;
    }while((c = getc(stream)) != EOF);
    string[len] = '\0'; //make it nullterminated
    return string;
}

node *new_node(FILE* stream)
// creates a new node from a line read by the readline() function.
{
    node *new = malloc(sizeof(node));
    new->string = readline(stream);
    new->p = NULL;
    return new;
}

void tail(node *newnode, node *head)
{
    node *tmp = head;
    while(tmp->p != NULL)
    {
        tmp = tmp->p;
    }
    tmp->p = newnode;
}

int main()
{
    FILE *moby = fopen("testtxt.txt", "r");
    if(moby == NULL) perror("FILE ERROR");
    node *head = new_node(moby);
    node *tmp;

    //constructing the list
    while((tmp = new_node(moby))->string != NULL)
    {
        tail(tmp, head);
    }

    //printing the list
    while(1){
        printf("%s", head->string);
        if(head->p == NULL) break; //end of linked list is reached
        head = head->p;
    }

    fclose(moby);
    return 0;
}

Especially the following part seems to have an issue with the way I constructed my 'strings':

while(1){
        printf("%s", head->string);
        if(head->p == NULL) break; //end of linked list is reached
        head = head->p;
    }

My understanding is that in order for printf to work with the %s modifier, the string must be nullterminated. I think I achieved that with the string[len] = '\0'; and from what the debugger is showing me, the way I implemented it is working. Screenshot of the debug. Also I let the debugger interpret it as an array so that I could see if the '\0' character is in the position I expect it to be, which is the case. Screenshot of the debug.

Now I am kind of at a loss since I can't find other examples of this problem and the debugger seems to show me that I am producing the right data.

I hope I just missed a minor detail that someone is able to spot.

TIA

(I am using eclipse and the output is consistent between win 10 console and eclipse console)

CodePudding user response:

There may be other problems but your use of realloc is wrong.

Here

realloc(string, (sizeof(char)*(len) 1));

you need to save the return value because that's where the allocated memory is.

Like

char* temp = realloc(string, (sizeof(char)*(len) 1));
if (temp == NULL)
{
    // add error handling
}
string = temp;

Unrelated to the described problem:

When you want to add new elements to the end of the list all the time, it's typically a good idea to have a tail pointer that points to the last element. That will make inserts much faster as you don't need the while(tmp->p != NULL) loop.

  • Related