C中的链表练习,有什么问题



下面的代码可以编译,但它不能按预期运行。我不确定我做错了什么,所以有人愿意告诉我我做错了什么以及我应该做得更好吗?我需要更改什么才能使其正常运行?

#include<stdio.h>
#include<stdlib.h>
typedef struct sub_Node
{
    int value;
    struct sub_Node *next;
}sub_Node;
typedef struct Node
{
    char *name;
    struct Node *next;
    struct sub_Node *sub_start;
}Node;
Node *start;

void add_player(char *name)
{
    Node *temp;
    temp = (Node *)malloc(sizeof(Node));
    temp->next = start;
    temp->name = name;
    temp->sub_start = (sub_Node *)malloc(sizeof(sub_Node));
    temp->sub_start->next = NULL;
    temp->sub_start->value = -1;
    start = temp;
}
void initialize()
{
    char *p;
    p = "";
    add_player(p);
}
void remove_player(char *name)
{
    Node *p;
    for(p = start; p!= NULL; p = p->next)
        if(p->name == name)
        {
            p->name = p->next->name;
            p->next = p->next->next;
        }
}
sub_Node* add_descending(sub_Node* sub_start, int piece_value)
{
    sub_Node *temp, *prev, *next;
    temp = (sub_Node *)malloc(sizeof(sub_Node));
    temp->value = piece_value;
    temp->next = NULL;
    prev = NULL;
    next = sub_start;
    while(next && next->value >= piece_value)
    {
        prev = next;
        next = next->next;
    }
    if(!next)
    {
        prev->next = temp;
    }
    else
    {
        if(prev)
        {
            temp->next = prev->next;
            prev->next = temp;
        }
        else
        {
            temp->next = sub_start;
            sub_start = temp;
        }
    }
    return sub_start;
}
void add_piece(char *name, int piece_value)
{
    Node *p;
    int c;
    for(p = start; p!=NULL; p = p->next)
        if(p->name == name)
            p->sub_start = add_descending(p->sub_start, piece_value);
}
void print_pieces(char *name)
{
    Node *p;
    sub_Node *q;
    for(p = start; p!=NULL; p = p->next)
        if(p->name == name)
        {
            printf("The values of the owned pieces are:");
            for(q = p->sub_start; q->value != -1; q = q->next)
                printf(" %d", q->value);
        }
}
int lose_piece(char *name)
{
    Node *p;
    sub_Node *q;
    int aux;
    for(p = start; p!=NULL; p = p->next)
        if(p->name == name)
        {
            for(q = p->sub_start; q->next->value != -1; q = q->next) {}
            aux = q->value;
            q->value = q->next->value;
            q->next = q->next->next;
            return aux;
        }
}
void print_players()
{
    Node *p;
    printf("The players are: ");
    for(p = start; p->name != ""; p = p->next)
        printf("%s ", p->name);
    printf("n");
}
int main()
{
    initialize();
    int y, value;
    char name[20];
    printf("Insert a digit to execute the desired task:n"
        "<0> end the programn"
        "<1> add a player, who doesn't own any piece yetn"
        "<2> remove a player and all his piecesn"
        "<3> print the name of all the playersn"
        "<4> a player gets a piecen"
        "<5> a player loses the piece with the lowest value out of the ones that he hasn"
        "<6> prints the pieces of a player in a descending order by valuenn");
    do
    {
        printf("digit: ");
        scanf("%d", &y);
        switch(y)
        {
            case 1:
                printf("Insert the player's name: ");
                scanf("%s", name);
                add_player(name);
                break;
            case 2:
                printf("Insert the player's name: ");
                scanf("%s", name);
                remove_player(name);
                break;
            case 3:
                print_players();
                break;
            case 4:
                printf("Insert the player's name:  ");
                scanf("%s", name);
                printf("Insert the value of the piece: ");
                scanf("%d", value);
                add_piece(name, value);
                break;
            case 5:
                printf("Insert the player's name: ");
                scanf("%s", name);
                printf("nThe player loses the piece: %dn", lose_piece(name));
                break;
            case 6:
                printf("Insert the player's name: ");
                scanf("%s", name);
                print_pieces(name);
        }
    } while(y != 0);
    return 0;
}

您的两个主要问题,其中此scanf("%d", value);值应通过引用传递,如下所示scanf("%d", &value);第二个是 C 中的字符串比较,就像在您的代码中一样 p->name != "" if(p->name == name)这是错误的,因为实际上您正在比较字符串的地址(它驻留在内存中的位置)而不是字符串值。 要比较 C 语言中的字符串,您必须使用 strcmp 和 family。

实际上有3个主要问题。 像在temp->name = name;中那样设置字符串值比这复杂一点。 因为您要从易失性的堆栈中分配temp->name一个字符串(堆栈更有可能在您从函数返回时无效)。 在您的情况下,您必须使用 malloc(和朋友)或仅使用 strdup 来分配一个新字符串。

作为对程序的稍微重写,您会发现许多建议,并且是有关如何构建代码以便于维护的良好起点。

仍然想建议您将成员和变量更改为更具声明性的名称,如 sub_startsub_Node 可以分别PieceNodepieces

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

typedef struct sub_Node
{
    int value;
    struct sub_Node *next;
}sub_Node;
typedef struct Node
{
    char *name;
    struct Node *next;
    struct Node *prev; // this to make life easyer
    struct sub_Node *sub_start;
}Node;

Node *start = NULL;

Node *find_player(char *name){
    Node *tmp = start;
    while( tmp ){
        if(strcmp(tmp->name,name) == 0 )
            break;
        tmp = tmp->next;
    }
    return tmp;
}
// int to return Error Code
// 
int add_player(char *name)
{
    Node *temp;
    if( find_player(name)) {
        printf("player %s already existsn", name);
        return 1;
    }
    // do not cast malloc
    temp = malloc(sizeof(Node));
    if( !temp ){
        printf ("not enough memoryn");
        return 2;
    }
    temp->name = strdup ( name);    // here was your error
    temp->sub_start = NULL;         // keep it simple
    temp->prev = NULL;
    temp->next = start;
    if(start)
        start->prev = temp;
    start = temp;
    return 0; // no error
}

void DestroyPieces(sub_Node* piece){
    if( piece ) {
        DestroyPieces( piece->next );
        free( piece );
    }
}
// as usual use int to return error code
int remove_player(char *name)
{
    Node *player = find_player(name);
    if ( !player ){
        return 1; // player not found
    }
    if ( player->next ){
        player->next->prev = player->prev;
    }
    if ( player->prev ){
        player->prev->next = player->next;
    }
    DestroyPieces(player->sub_start);
    free(player->name);
    free(player);
    return 0; // success
}
sub_Node* new_piece(int value){
    sub_Node *temp = malloc( sizeof(sub_Node) );
    if(temp){
        temp->value = value;
        temp->next = NULL;
    }
    return temp;
}
// int to return error code
// pass sub_start as pointer to pointer, as it might be updated
int  add_descending(sub_Node** psub_start, int piece_value)
{
    sub_Node *piece, *current, *prev = NULL;
    if( !psub_start){
        return 5; // this should not happen
    }
    current = *psub_start;
    piece = new_piece( piece_value );
    if( !piece ) return 1; // no mem
    if(!current){
        // this is the first and only one
        *psub_start = piece;
        return 0; // OK
    }

    while(current && current->value >= piece_value)
    {
        prev        = current;
        current     = current->next;
    }
    if( prev )
        prev->next  = piece;
    piece->next = current;
    if( current == *psub_start ){
        *psub_start = piece;
    }
    return 0 ; // OK
}
void add_piece(Node * player, int piece_value)
{
    if ( !player) {
        return ;
    }
    if(add_descending (&(player->sub_start), piece_value) == 0 )
        return ; //OK
    printf("an error occured while adding a piece (%d) to player '%s'n",piece_value,player->name);
}

void print_pieces(Node *player)
{
    sub_Node *q;
     if( !player ){
        return;
    }   

    if( !player->sub_start ){
        printf("Player '%s' has no piecesn",player->name);
        return;
    }
    printf("The values of the owned pieces are:");
    for(q = player->sub_start; q != NULL; q = q->next)
        printf(" %d", q->value);
    printf("n");
}
void lose_piece(Node *player)
{
    if( !player ){
        return;
    }
    sub_Node *q, *prev = NULL;
    int aux;

    if( !player->sub_start ){
        printf("Player '%s' has no piecesn",player->name);
        return;
    } 

    // i think you want drop the last one
    for(q = player->sub_start; q->next != NULL ;prev = q, q = q->next) {
        ;
    }
    if(prev)
        prev->next = NULL;
    else
        player->sub_start = NULL;
    aux = q->value;
    free(q);
    printf("nThe player loses the piece: %dn", aux);
    return;
}
void print_players()
{
    Node *p;
    if( !start ){
        printf("there are no players, try to add somen");
        return;
    }
    printf("The players are: ");
    for(p = start; p != NULL; p = p->next)
        printf("%s ", p->name);
    printf("n");
}
void print_menu(void){
    printf("Insert a digit to execute the desired task:n"
        "<0> end the programn"
        "<1> add a player, who doesn't own any piece yetn"
        "<2> remove a player and all his piecesn"
        "<3> print the name of all the playersn"
        "<4> a player gets a piecen"
        "<5> a player loses the piece with the lowest value out of the ones that he hasn"
        "<6> prints the pieces of a player in a descending order by valuenn");
}
Node * get_player(char *name){
    Node *player = find_player(name);
    if(!player)
        printf("Player '%s' do not existsn",name);
    return player;
}
int main()
{
    // initialize(); no more needed
    int     y, value;
    char    name[20];
    Node    *player;

    print_menu();
    do
    {
        printf("digit: ");
        scanf("%d", &y);
        switch(y)
        {
            case 1:
                printf("Insert the player's name: ");
                scanf("%s", name);
                add_player(name);
                break;
            case 2:
                printf("Insert the player's name: ");
                scanf("%s", name);
                player = get_player(name);
                if( player )

                break;
            case 3:
                print_players();
                break;
            case 4:
                printf("Insert the player's name:  ");
                scanf("%s", name);
                player = get_player(name);
                if( player ){
                    printf("Insert the value of the piece: ");
                    scanf("%d", &value);
                    add_piece(player, value);
                }
                break;
            case 5:
                printf("Insert the player's name: ");
                scanf("%s", name);
                player = get_player(name);
                lose_piece(player);
                break;
            case 6:
                printf("Insert the player's name: ");
                scanf("%s", name);
                player = get_player(name);
                print_pieces(player);
        }
    } while(y != 0);
    return 0;
}

相关内容

  • 没有找到相关文章

最新更新