1

im new to programming and learning data structures at the moment, i am working on a program that takes input from a file in the following format :

*TEAM1
1-player1 
2-player2 
3-player3 
4-player4 
5-player5 
6-player6 
7-player7 
8-player8 
9-player9 
10-player10 
11-player11 
12-player12 
13-player13 
14-player14 
15-player15 
16-player16 
17-player17 
18-player18 
19-player19 
20-player20 
21-player21 
22-player22 
*TEAM2
1-player1 
2-player2 
3-player3 
4-player4 
5-player5 
6-player6 
7-player7 
8-player8 
9-player9 
10-player10 
11-player11 
12-player12 
13-player13 
14-player14 
15-player15 
16-player16 
17-player17 
18-player18 
19-player19 
20-player20 
21-player21 
22-player22 
23-player23
24-player24
25-player25

im using a nested linked list because I need each team have its own linked list of players, and if there are more than 11 players in the team they will be inserted into a queue for the same team only

these are the linked lists I created:

typedef struct PLAYERS{

    int num;
    char name [50];
    struct PLAYERS* next;

}PLAYERS;

typedef struct QUEUE{

    PLAYERS* front;
    PLAYERS* rear;

}QUEUE;

typedef struct teamList{

    char code [50];
    PLAYERS* player;
    QUEUE* playerQueue;
    struct teamList* next;

}teamList;

my issue Right now is when I try to insert values from the file in the "Player" linked list part of the nested linked list. it seems like it only saves the latest value inserted into it only, that was made clear to me when I tried to print the contents of the player linked list for a specific team and it only printed the last inserted value, which was 11-player11, then when I tried to print the next value in the list the program finished executing with a NULL value, which im assuming means I tried to print the NULL value the list is pointing at.

here are the parts of the code related to this issue:

teamList* MakeEmptyList(teamList* L) {
    L = (teamList*)malloc(sizeof(teamList)); 

    if(L == NULL) 
        printf("Out of memory!\n");

    L->player = makePlayer(L->player); ;
    L->playerQueue = makeQueue(L->playerQueue);
    L->next = NULL;
    return L;
}

PLAYERS* makePlayer(PLAYERS* player){

    player = (PLAYERS*)malloc(sizeof(PLAYERS));
    player->next = NULL;
    return player;
}

void readFile(teamList* team){

    teamList* temp = team;
    FILE *f = fopen("teamsinfo.txt","r");
    int i, counter = 1;
    char playerName [50];
    char teamCode [50];


    if(fscanf(f," *%s",teamCode)> 0){
            printf("*%s\n", teamCode);
            strcpy(temp->code,teamCode);
    }
    while(!feof(f)){
                if(fscanf(f," *%s",teamCode)> 0){
                    counter = 1;
                    temp->next = MakeEmptyList(temp->next);
                    temp =temp->next;

                    strcpy(temp->code,teamCode);
                }
                 else if(counter<12){
                    if(fscanf(f," %d-%s",&i,playerName)> 0){
                        temp->player = insert(playerName,i,temp->player);
                        temp->player = temp->player->next;

                        }
                        counter++;
                        }
                    else if(counter >11){
                            if(fscanf(f," %d-%s",&i,playerName)> 0){
                        enQueue(temp->playerQueue,playerName,i);
                    }
                }
                   }

    fclose(f);
}

PLAYERS* insert(char x[],int num, PLAYERS* p) {
    PLAYERS* temp ; 
    temp = (PLAYERS*)malloc(sizeof (PLAYERS));
    strcpy(temp->name,x);
    temp->num = num;
    temp->next=p->next; 
       
    p->next=temp; 
    return p;
}

how can this be solved?

  • 1
    Trashed output is usually a sign of failed `NUL` termination on your C strings. – tadman Dec 16 '22 at 14:38
  • It's really hard to review this much code. Can you trim it down to a more _minimal_ form? One thing that helps is to test *each function* independently before assembling. – tadman Dec 16 '22 at 14:39
  • Tip: Consider using `calloc()` instead of `malloc()` as that will zero out your allocations, and makes it clear how you're computing the actual size of the allocation. Additionally, in C there's no need to cast your allocations. – tadman Dec 16 '22 at 14:40
  • You should be absolutely sure that your `fscanf` calls are producing valid data before proceeding. Use a debugger to validate this. – tadman Dec 16 '22 at 14:42
  • ⟼Remember, it's always important, *especially* when learning and asking questions on Stack Overflow, to keep your code as organized as possible. [Consistent indentation](https://en.wikipedia.org/wiki/Indentation_style) helps communicate structure and, importantly, intent, which helps us navigate quickly to the root of the problem without spending a lot of time trying to decode what's going on. – tadman Dec 16 '22 at 14:42

1 Answers1

0

Give this a try. It loads and displays the test file.
while ( ! feof ( f)) is almost always wrong. Why is “while( !feof(file) )” always wrong? has an explanation.
This uses while ( fgets (...)) to read the file, line by line.
Then use sscanf to parse the lines.

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

typedef struct PLAYERS {
    int num;
    char name[50];
    struct PLAYERS* next;
} PLAYERS;

typedef struct QUEUE {
    PLAYERS* front;
    PLAYERS* rear;
} QUEUE;

typedef struct teamList {
    char code [50];
    PLAYERS* player;
    QUEUE* playerQueue;
    struct teamList* next;
} teamList;

teamList *readFile ( teamList* team);
PLAYERS* makePlayer ( PLAYERS* player);
QUEUE* makeQueue ( QUEUE* q);
void DeleteTeamList ( teamList* L);
teamList* MakeEmptyList ( teamList* L);
QUEUE *enQueue ( QUEUE* q, char names[], int number);
teamList *insert ( char y[], int num, teamList* p);
void printStrings ( teamList* x);

int main ( void) {
    teamList* teams = NULL;

    // teams = MakeEmptyList ( teams);
    teams = readFile ( teams);
    printStrings ( teams);
    DeleteTeamList ( teams);
}


teamList *readFile(teamList* team) {
    int i = 0;
    int counter = 1;
    char playerName[50] = "";
    char teamCode[50] = "";
    char text[100] = "";
    teamList* temp = team;
    FILE *f = NULL;

    if ( NULL != ( f = fopen("teamsinfo.txt","r"))) {
        while( fgets ( text, sizeof text, f)) {
            if( 1 == sscanf ( text, " *%49s", teamCode)) {
                counter = 1;
                if ( temp) {
                    temp->next = MakeEmptyList ( temp->next);
                    temp = temp->next;
                } else {
                    temp = MakeEmptyList ( temp);
                    team = temp;
                }
                strcpy ( temp->code, teamCode);
            } else if ( 2 == sscanf ( text, "%d-%s", &i, playerName)) {
                if ( counter < 12) {
                    temp = insert ( playerName, i, temp);
                } else if ( counter > 11) {
                    temp->playerQueue = enQueue ( temp->playerQueue, playerName, i);
                }
                counter++;
            }
        }
        fclose ( f);
    } else {
        perror ( "teamsinfo.txt");
    }
    return team;
}

PLAYERS* makePlayer ( PLAYERS* player) {
    player = malloc ( sizeof *player);
    player->next = NULL;
    return player;
}

QUEUE* makeQueue ( QUEUE* q) {
    q = malloc ( sizeof *q);
    q->front = q->rear = NULL;
    return q;
}

void DeleteTeamList ( teamList* L) {
    teamList* P = NULL;
    teamList* temp = NULL;

    P = L;
    while(P != NULL) {
        PLAYERS *player = P->player;
        while ( player != NULL) {
            PLAYERS *hold = player->next;
            free ( player);
            player = hold;
        }
        player = P->playerQueue->front;
        while ( player != NULL) {
            PLAYERS *each = player->next;
            free ( player);
            player = each;
        }
        temp = P->next;
        free ( P);
        P = temp;
    }
}

teamList* MakeEmptyList ( teamList* L) {
    if(L != NULL) {
        DeleteTeamList( L );
    }
    if ( NULL == ( L = malloc ( sizeof *L))) {
        fprintf ( stderr, "problem malloc L\n");
        return NULL;
    }

    L->player = NULL;
    L->playerQueue = NULL;
    L->next = NULL;
    return L;
}

QUEUE *enQueue ( QUEUE* q, char names[], int number) {
    QUEUE* temp = q;
    if ( ! temp) {
        temp = makeQueue ( temp);
    }
    PLAYERS *player = NULL;
    if ( NULL == ( player = calloc ( 1, sizeof *player))) {
        fprintf ( stderr, "problem calloc player\n");
        return q;
    }
    strcpy ( player->name, names);
    player->num = number;

    if ( ! q || ! q->rear) {
        temp->front = temp->rear = player;
        printf("----------------- %d-%s -----------------------\n"
        ,temp->rear->num, temp->rear->name);
        return temp;
    }

    player->next = q->rear;
    q->rear = player;
    printf("----------------- %d-%s -----------------------\n"
    ,q->rear->num, q->rear->name);
    return q;
}

teamList *insert ( char x[], int num, teamList* p) {
    PLAYERS* temp;
    temp = malloc ( sizeof *temp);
    strcpy ( temp->name, x);
    temp->num = num;
    temp->next = p->player;

    p->player = temp;
    return p;
}

void printStrings ( teamList* x) {
    teamList* p = x;

    while ( p != NULL) {
        PLAYERS *players = p->player;
        while ( players != NULL) {
            printf ( "%s\n", p->code);
            printf ( "%d-%s\n", players->num, players->name );
            players = players->next;
        }
        p = p->next;
    }
    printf("\n");
}
user3121023
  • 8,181
  • 5
  • 18
  • 16