Ilya Glushchenko
Ilya Glushchenko

Reputation: 327

Doubly linked list always contains only 1 record

I am writing a simple program for working with structures in C++, but there is a problem I can't solve.

My program receives few structures as an input. It is supposed to sort them by the key and print them. But with my code I have always only one structure in my list:

#include "iostream"
#include "string.h"
#include "limits"  //ignore max
#include "stdlib.h"//atof
using namespace std; 

struct Struct {
    char text[10];
    int age;
    Struct* prev;
    Struct* next;
};

int input(string msg) {
    char str[2];
    int check = 0, len = 0,
    var = 0,
        i = 0;
    while (1) {
        cout << msg;
        cin.getline(str, 2);
        if (cin.fail()) {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
        len = strlen(str);
        check = 0;
        for (i = 0; i < len; i++) {
            if (isdigit(str[i])) {
                check++;
            }
        }
        if (check == len && !(check == 1 && str[0] == '-') && check != 0 && atoi(str) != 0) {
            var = atoi(str);
            return var;
        } else {
            cout << "Error!" << endl;
        }

    }
}

Struct* add_struct_to_list(Struct* prev) {
    Struct* NewStruct = 0;
    char str[10];
    int age;
    cout << "Name: ";
    cin.getline(str, 10);
    if (cin.fail()) {
        cin.clear();
        cin.ignore(numeric_limits <streamsize>::max(), '\n');
    }
    age = input("Age: ");
    NewStruct = new Struct;
    strcpy(NewStruct->text, str);
    NewStruct->age = age;
    NewStruct->prev = prev;
    NewStruct->next = 0;
    return NewStruct;
}

Struct* start_new_list(int number) {
    Struct* NewList = 0;
    NewList = add_struct_to_list(0);
    Struct* NewStruct = NewList;
    int counter = 1;
    for (counter; counter < number; counter++) {
        NewStruct = add_struct_to_list(NewStruct);
    }
    return NewList;
}

void delete_all_list(Struct* list_begin) {
    Struct* to_delete = list_begin->next;
    Struct* next = 0;
    delete[] list_begin;
    if (to_delete != 0) {
        do {
            next = to_delete->next;
            delete[] to_delete;
        } while (next != 0);
    }
}

void sort_by_age(Struct* list_begin) {
    Struct* node = 0;
    Struct* node2 = 0;
    int age;
    for (node = list_begin; node; node = node->next) {
        for (node2 = list_begin; node2; node2 = node2->next) {
            if (node->age < node2->age) {
                age = node->age;
                node->age = node2->age;
                node2->age = age;
            }
        }
    }
}

void print_list(Struct* list_begin) {
    for (Struct* node = list_begin; node; node = node->next) {
        cout << "Age: " << node->age << "; Name: " << node->text << endl;
    }
}

int main() {
    int number = input("Number of students: ");
    Struct* NewList = start_new_list(number);
    sort_by_age(NewList);
    print_list(NewList);
    delete_all_list(NewList);
    return 0;
}

Input:

 Number of students: 3
 Name: as
 Age: 1
 Name: as
 Age: 2
 Name: as
 Age: 3

Output:

Age: 1; Name: as

Also note that this is homework and I must use structs.

UPD: Thanks to all for help!

Upvotes: 1

Views: 368

Answers (2)

LihO
LihO

Reputation: 42083

You are trying to iterate through your list by using node->next pointer:

for (Struct* node = list_begin; node; node = node->next) {
    cout << "Age: " << node->age << "; Name: " << node->text << endl;
}

But the way you are adding new Structs into your list is wrong, because you always set next to 0:

Struct* add_struct_to_list(Struct* prev) {
    ...
    NewStruct->prev = prev;
    NewStruct->next = 0;
    return NewStruct;
}

Even if you allocate 3 new Structs, all of them will have pointer to next equal to 0. Proper way of adding new Struct to your list could look like this:

Struct* start_new_list(int number) {
    Struct* prevStruct = NULL;
    Struct* newList = NULL;                 // pointer to the first struct
    for (int counter = 0; counter < number; counter++) {
        Struct* newStruct = add_struct_to_list(prevStruct);
        if (prevStruct)                     // if there was previous struct:
            prevStruct->next = newStruct;   // make it point to new struct
        if (counter == 0)                   // if it is first allocated struct:
            newList = newStruct;            // store its address
        prevStruct = newStruct;             // store last struct as "prev"
    }
    return newList;
}

Also note that when you allocate memory by calling new, you should free it by calling delete. You are using delete[], which should be used when you allocate with new[]. Cleaning up your list should look like this:

void delete_all_list(Struct* list_begin) {
    Struct* structToDelete = NULL;
    Struct* node = list_begin;
    while (node->next) {
        structToDelete = node;
        node = node->next;
        delete structToDelete;
    }
    delete node;
}

Hope this helps :)

Upvotes: 1

Jeremy SH
Jeremy SH

Reputation: 126

NewStruct->next is always 0. Is this what you expect?

Also, you probably want to sort the structs as a unit rather than changing people's ages!

Upvotes: 0

Related Questions