1

C++ で構造体を操作するための簡単なプログラムを作成していますが、解決できない問題があります。

私のプログラムは、入力として構造体をほとんど受け取りません。それらをキーでソートして印刷することになっています。しかし、私のコードでは、リストには常に 1 つの構造しかありません。

#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;
}

入力:

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

出力:

Age: 1; Name: as

また、これは宿題であり、s を使用する必要structがあることに注意してください。

UPD: 助けてくれてありがとう!

4

2 に答える 2

1

node->nextポインタを使用してリストを反復処理しようとしています。

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

ただし、常に次のように設定してStructいるため、リストに新しいを追加する方法は間違っています。next0

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

3つの新しいを割り当てたとしてもStruct、それらすべてにnext等しいポインタがあります0。リストに新規を追加する適切な方法は、次のStructようになります。

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;
}

また、を呼び出してメモリを割り当てる場合はnew、を呼び出してメモリを解放する必要があることに注意してくださいdelete。を使用delete[]しています。これは、で割り当てるときに使用する必要がありますnew[]。リストのクリーンアップは次のようになります。

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;
}

お役に立てれば :)

于 2013-02-10T10:58:49.850 に答える
0

NewStruct->next は常に 0 です。これでよろしいですか?

また、人々の年齢を変更するのではなく、構造体を 1 つの単位として並べ替えたいと思うでしょう。

于 2013-02-10T11:11:03.057 に答える