SO YEH MY problem is its not reading the whole file and inputing it to the stucture..
i believe that the problem lies in the adt.( the last source code on the bottom)
in the private adt search function, insert function, and traversal.....
ive been wreking my brains out trying to figure it out but
i need to get this right ..... T____T
any help would be cool
input.txt file
HU Hungary; Budapest; 10006835
MX Mexico; Mexico City; 106202903
CN China; Beijing; 1306313812
NP Nepal; Kathmandu; 27676547
MU Mauritius; Port Louis; 123060
HEADER file
/*
This header file contains the functions to maintain
and process a linked list.
*/
// Singly-Linked List ADT Type Definitions
typedef struct node
{
struct node* prev;
struct node* forw;
void *dataPtr;
} NODE;
typedef struct
{
int count;
NODE* pos;
NODE* head;
NODE* rear;
int (*compare) (void* argu1, void* argu2);
} LIST;
// List ADT Prototype Declarations: public functions
LIST* createList (int (*compare)
(void* argu1, void* argu2));
LIST* destroyList (LIST* list);
int addNode (LIST* pList, void* dataInPtr);
int removeNode (LIST* pList,
void* keyPtr,
void** dataOutPtr);
int searchList (LIST* pList,
void* pArgu,
void** pDataOut);
int retrieveNode (LIST* pList,
void* pArgu,
void** dataOutPtr);
int traverse (LIST* pList,
int fromWhere,
void** dataOutPtr);
int reverse (LIST* pList,
int fromWhere,
void** dataOutPtr);
int listCount (LIST* pList);
int emptyList (LIST* pList);
int fullList (LIST* pList);
main FILE
*/
#include <stdio.h>
#include <stdlib.h>
#include <cType.h>
#include <string.h>
#include <crtdbg.h>
#include "linkListADT.h"
typedef struct
{
char ID[3];
char* country;
char* cap;
long int pop;
} COUNTRY;
LIST* buildList (void);
void printInstr (void);
void process (LIST* list);
char getChoice (void);
void printList (LIST* list);
void printCount (LIST* list);
void search (LIST* list);
void delete_info (LIST* list);
void insert_info (LIST* list);
void print_capital (LIST* list);
void reverseList (LIST* list);
int cmpID (void* pID1, void* pID2);
int main (void)
{
// Local Definitions
LIST* list;
COUNTRY *borders;
printInstr ();
list = buildList ();
process (list);
traverse (list, 0, (void**)&borders);
do
{
free(borders->country);
free(borders->cap);
} while (traverse (list, 1, (void**)&borders));
printf("\n");
list = destroyList(list);
printf("\n\t\tEnd of program - LINKED LISTS"
"\n\t\tHave a great day!\n");
printf( _CrtDumpMemoryLeaks() ? "Memory Leak\n" : "No Memory Leak\n");
system("pause");
return 0;
} // main
/* ================== printInstr =================
Print instructions to user.
Pre nothing
Post instructions printed
*/
void printInstr (void)
{
// Statements
printf("U Can Do IT!!!!!!!\n");
return;
} // instr
/* ==================== cmpID ====================
Compares two years in PICTURE structures
Pre year1 is a pointer to the first structure
year2 is a pointer to the second structure
Post two years compared and result returned
Return -1 if year1 less; 0 if equal; +1 greater
*/
int cmpID (void* pID1, void* pID2)
{
// Local Definitions
int result;
char ID1[3];
char ID2[3];
// Statements
strcpy(ID1 , ((COUNTRY*)pID1)->ID);
strcpy(ID2 , ((COUNTRY*)pID2)->ID);
if (strcmp(ID1, ID2) < 0)
result = -1;
else if (strcmp(ID1, ID2) > 0)
result = +1;
else
result = 0;
return result;
} // cmpYear
/* ==================== buildList ====================
Reads a text data file and loads the linked list
Pre file exists in format: yy \t 'pic' \t 'dir'
Post list contains data
-or- program aborted if problems
*/
LIST* buildList (void)
{
// Local Definitions
FILE* fpData;
LIST* list;
COUNTRY* borders;
int addResult;
char buffer[60];
char tcountry[20];
char tcap[15];
// Statements
list = createList (cmpID);
if (!list)
printf("\aCannot create list\n"),
exit (100);
fpData = fopen("countries.txt", "r");
if (!fpData)
printf("\aError opening input file\n"),
exit (110);
while (fgets(buffer, sizeof(buffer)-1, fpData))
{
borders = (COUNTRY*) malloc(sizeof(COUNTRY));
if (!(borders))
printf("\aOut of Memory in build list\n"),
exit (100);
sscanf(buffer,"%2s %[^;] %*c %[^;] %*c %ld", borders->ID , tcountry, tcap, &borders->pop);
borders->country = (char*) calloc (strlen(tcountry)+1, sizeof(char));
strcpy(borders->country, tcountry);
borders->cap = (char*) calloc (strlen(tcap)+1, sizeof(char));
strcpy(borders->cap, tcap);
// Insert into list
addResult = addNode (list, borders);
if (addResult != 0)
if (addResult == -1)
printf("Memory overflow adding movie\a\n"),
exit (120);
else
printf("Duplicate ID: %s not added\n", borders->ID);
} // while
fgetc(fpData);
return list;
} // buildList
/* ================== printList ==================
Prints the entire list
Pre list has been created
Post list printed
*/
void printList (LIST* list)
{
// Local Definitions
COUNTRY* borders;
// Statements
// Get first node
if (listCount (list) == 0)
printf("Sorry, nothing in list\n\n\a");
else
{
traverse (list, 0, (void**)&borders);
printf("================\n");
do
{
printf("%s %s %s %ld\n",borders->ID, borders->country, borders->cap, borders->pop);
} while (traverse (list, 1, (void**)&borders));
printf("\n");
} // else
} // printList
/* ================== revereseList ==================
Prints the entire list
Pre list has been created
Post list printed
*/
void reverseList (LIST* list)
{
// Local Definitions
COUNTRY* borders;
// Statements
// Get first node
if (listCount (list) == 0)
printf("Sorry, nothing in list\n\n\a");
else
{
reverse (list, 0, (void**)&borders);
printf("================\n");
do
{
printf("%s %s %s %ld\n",borders->ID, borders->country, borders->cap, borders->pop);
} while (reverse (list, 1, (void**)&borders));
printf("\n");
} // else
} // printList
/* =================== process ===================
Process user choices
Pre list has been created
Post all of user's choice executed
*/
void process (LIST* list)
{
// Local Definitions
char choice;
// Statements
do
{
choice = getChoice ();
switch (choice)
{
case 'P': printList (list);
break;
case 'B': reverseList (list);
break;
case 'L': print_capital (list);
break;
case 'S': search (list);
break;
case 'I': insert_info (list);
break;
case 'D': delete_info (list);
break;
case 'C': printCount (list);
break;
case 'M': process (list);
break;
case 'E': break;
} // switch
} while (choice != 'E');
return;
} // process
/* ================== getChoice ==================
Prints the menu of choices.
Pre nothing
Post menu printed and choice returned
*/
char getChoice (void)
{
// Local Definitions
char choice;
int valid;
// Statements
printf("======== MENU ======= \n"
"P : Print Forward\n"
"B : Print Backward\n"
"L : Print the countries whose capital\n"
" begins with a letter of choice\n"
"S : Search \n"
"I : Insert\n"
"D : Delete \n"
"C : Display the number of elements in the list\n"
"M : Print Menu \n"
"E : Exit. \n");
do
{
printf("\nCHOICE :");
scanf(" %c", &choice);
choice = toupper(choice);
printf("\n");
switch (choice)
{
case 'P': //chk
case 'B':
case 'L':
case 'S': //chk
case 'I': //chk
case 'D': //chk
case 'C': //chk
case 'M': //chk
case 'E': valid = 1;
break;
default: valid = 0;
printf("\aInvalid choice\n"
"Please try again: ");
break;
} // switch
} while (!valid);
return choice;
} // getChoice
/* ==================== search ====================
Searches for year and prints year, picture, and
director.
Pre list has been created
user has selected search option
Post year printed or error message
*/
void search (LIST* list)
{
// Local Definitions
char ID[3];
int found;
int i;
COUNTRY pSrchArgu;
COUNTRY* borders;
// Statements
printf("Enter Country ID: ");
scanf ("%s", ID);
for(i=0; i<2; i++)
ID[i] = toupper(ID[i]);
strcpy(pSrchArgu.ID, ID);
found = searchList (list, &pSrchArgu, (void**)&borders);
if (found)
printf("%s %s %s %ld\n",borders->ID, borders->country, borders->cap, borders->pop);
else
printf("Sorry, but %s is not available.\n", ID);
fgetc(stdin);
} // search
/* ==================== delete_info ====================
Searches for year and prints year, picture, and
director.
Pre list has been created
user has selected search option
Post year printed or error message
*/
void delete_info (LIST* list)
{
// Local Definitions
char ID[3];
int found;
int i;
COUNTRY pSrchArgu;
COUNTRY* borders;
// Statements
printf("Enter Country ID: ");
scanf ("%s", ID);
for(i=0; i<2; i++)
ID[i] = toupper(ID[i]);
strcpy(pSrchArgu.ID, ID);
found = searchList (list, &pSrchArgu, (void**)&borders);
if (found)
{
removeNode(list, &pSrchArgu,(void**)&borders);
printf("ID: %s and any info involving it has been deleted\n\n", ID);
}
else
printf("Sorry, but %s is not available.\n", ID);
} // search
/* ==================== insert_info ====================
Searches for year and prints year, picture, and
director.
Pre list has been created
user has selected search option
Post year printed or error message
*/
void insert_info (LIST* list)
{
// Local Definitions
char ID[3];
int found;
int i;
char tcountry[20];
char tcap[15];
COUNTRY pSrchArgu;
COUNTRY* borders;
COUNTRY* borders_new;
// Statements
printf("Enter Country ID you want to enter to the list: ");
scanf ("%s", ID);
for(i=0; i<2; i++)
ID[i] = toupper(ID[i]);
strcpy(pSrchArgu.ID, ID);
found = searchList (list, &pSrchArgu, (void**)&borders);
if (found)
printf("Sorry, but %s is can not have duplicates.\n"
"Its already in the list.\n", ID);
else
{
borders_new = (COUNTRY*) malloc(sizeof(COUNTRY));
strcpy(borders_new->ID, ID);
printf("ENTER COUNTRY NAME:");
scanf ("%s", tcountry);
borders_new->country = (char*) calloc (strlen(tcountry)+1, sizeof(char));
strcpy(borders_new->country, tcountry);
printf("ENTER COUNTRY's CAPITAL NAME:");
scanf ("%s", tcap);
borders_new->cap = (char*) calloc (strlen(tcap)+1, sizeof(char));
strcpy(borders_new->cap, tcap);
printf("ENTER COUNTRY NO. of POPULATION:");
scanf ("%ld", &borders_new->pop);
i = addNode (list, borders_new);
if (i != 0)
if (i == -1)
printf("Memory overflow adding movie\a\n"),
exit (120);
else
;
else
printf("Country added\n");
}
} // search
/* ==================== printCount ====================
Pre L
Post
*/
void printCount (LIST* list)
{
printf("The number of elements in the list are: %d\n\n", list->count);
return;
}
/* ================== print_capital ==================
Prints the entire list
Pre list has been created
Post list printed
*/
void print_capital (LIST* list)
{
// Local Definitions
COUNTRY* borders;
char capital;
// Statements
fgetc(stdin);
printf("ENTER CAPITAL's FIRST LETTER\n");
scanf("%c", &capital);
// Get first node
if (listCount (list) == 0)
printf("Sorry, nothing in list\n\n\a");
else
{
traverse (list, 0, (void**)&borders);
printf("================\n");
do
{
if(borders->cap[0] == toupper(capital))
printf("%s %-15s %-15s %-5ld\n",borders->ID, borders->country, borders->cap, borders->pop);
} while (traverse (list, 1, (void**)&borders));
printf("\n");
} // else
} // printList
ADTlink.c
/*
This file contains the definitons of the functions to maintain
and process a linked list:
Public Functions:
createList
addNode
removeNode
searchList
retrieveNode
emptyList
fullList
listCount
traverse
destroyList
Private Functions:
_insert
_delete
_search
*/
#include <stdlib.h>
#include "linkListADT.h" /* <== public functions */
/* private functions */
static int _insert (LIST* pList, NODE* pPre, NODE* pSuc, void* dataInPtr);
static void _delete (LIST* pList, NODE* pPre, NODE* pLoc, NODE* pSuc, void** dataOutPtr);
static int _search (LIST* pList, NODE** pPre, NODE** pLoc, NODE** pSuc, void* pArgu);
/*
=================================================
============== Public Functions =================
=================================================
*/
/* =============== createList ==============
Allocates dynamic memory for a list head
node and returns its address to caller
Pre compare is address of compare function
used to compare two nodes.
Post head has allocated or error returned
Return head node pointer or null if overflow
*/
LIST* createList (int (*compare) (void* argu1, void* argu2))
{
// Local Definitions
LIST* list;
NODE* lead;
NODE* tail;
// Statements
list = (LIST*) malloc (sizeof (LIST));
lead = (NODE*) malloc (sizeof (NODE));
tail = (NODE*) malloc (sizeof (NODE));
if (list)
{
list->head = lead;
list->pos = NULL;
list->rear = tail;
list->count = 0;
lead->forw = tail;
lead->prev = NULL;
lead->dataPtr = NULL;
tail->forw = NULL;
tail->prev = lead;
tail->dataPtr = NULL;
list->compare = compare;
} // if
return list;
} // createList
/* ================== addNode =================
Inserts data into list.
Pre pList is pointer to valid list
dataInPtr pointer to insertion data
Post data inserted or error
Return -1 if overflow
0 if successful
1 if dupe key
*/
int addNode (LIST* pList, void* dataInPtr)
{
// Local Definitions
int found;
int success;
NODE* pPre;
NODE* pLoc;
NODE* pSuc;
// Statements
found = _search (pList, &pPre, &pLoc, &pSuc, dataInPtr);
if (found)
// Duplicate keys not allowed
return (+1);
success = _insert (pList, pPre, pSuc, dataInPtr);
if (!success)
// Overflow
return (-1);
return (0);
} // addNode
/* ================= removeNode ================
Removes data from list.
Pre pList pointer to a valid list
keyPtr pointer to key to be deleted
dataOutPtr pointer to data pointer
Post Node deleted or error returned.
Return false not found; true deleted
*/
int removeNode (LIST* pList, void* keyPtr, void** dataOutPtr)
{
// Local Definitions
int found;
NODE* pPre;
NODE* pLoc;
NODE* pSuc;
// Statements
found = _search (pList, &pPre, &pLoc, &pSuc, keyPtr);
if (found)
_delete (pList, pPre, pLoc, pSuc, dataOutPtr);
return found;
} // removeNode
/* ================== searchList =================
Interface to search function.
Pre pList pointer to initialized list.
pArgu pointer to key being sought
Post pDataOut contains pointer to found data
-or- NULL if not found
Return boolean true successful; false not found
*/
int searchList (LIST* pList, void* pArgu, void** pDataOut)
{
// Local Definitions
int found;
NODE* pPre;
NODE* pLoc;
NODE* pSuc;
// Statements
found = _search (pList, &pPre, &pLoc, &pSuc, pArgu);
if (found)
*pDataOut = pLoc->dataPtr;
else
*pDataOut = NULL;
return found;
} // searchList
/* ================== retrieveNode ================
This algorithm retrieves data in the list without
changing the list contents.
Pre pList pointer to initialized list.
pArgu pointer to key to be retrieved
Post Data (pointer) passed back to caller
Return boolean true success; false underflow
*/
int retrieveNode (LIST* pList, void* pArgu, void** dataOutPtr)
{
// Local Definitions
int found;
NODE* pPre;
NODE* pLoc;
NODE* pSuc;
// Statements
found = _search (pList, &pPre, &pLoc, &pSuc, pArgu);
if (found)
{
*dataOutPtr = pLoc->dataPtr;
return 1;
} // if
*dataOutPtr = NULL;
return 0;
} // retrieveNode
/* ================= emptyList ================
Returns boolean indicating whether or not the
list is empty
Pre pList is a pointer to a valid list
Return boolean true empty; false list has data
*/
int emptyList (LIST* pList)
{
// Statements
return (pList->count == 0);
} // emptyList
/* ================== fullList =================
Returns boolean indicating no room for more data.
This list is full if memory cannot be allocated for
another node.
Pre pList pointer to valid list
Return boolean true if full
false if room for node
*/
int fullList (LIST* pList)
{
// Local Definitions
NODE* temp;
// Statements
if ((temp = (NODE*)malloc(sizeof(*(pList->head->forw)))))
{
free (temp);
return 0;
} // if
// Dynamic memory full
return 1;
} // fullList
/* ================== listCount ==================
Returns number of nodes in list.
Pre pList is a pointer to a valid list
Return count for number of nodes in list
*/
int listCount(LIST* pList)
{
// Statements
return pList->count;
} // listCount
/* ================== reverse =================
Reversely traverses a list. Each call either starts at the
beginning of list or returns the location of the
next element in the list.
Pre pList pointer to a valid list
fromWhere 0 to start at first element
dataPtrOut address of pointer to data
Post if more data, address of next node
Return true node located; false if end of list
*/
int reverse (LIST* pList,
int fromWhere,
void** dataPtrOut)
{
// Statements
if (pList->count == 0)
return 0;
if (fromWhere == 0)
{
//Start from first node
pList->pos = pList->rear->prev;
*dataPtrOut = pList->pos->dataPtr;
return 1;
} // if fromwhere
else
{
// Start from current position
if (pList->pos->prev == pList->head)
return 0;
else
{
pList->pos = pList->pos->prev;
*dataPtrOut = pList->pos->dataPtr;
return 1;
} // if else
} // if fromwhere else
} // traverse
/* ================== traverse =================
Traverses a list. Each call either starts at the
beginning of list or returns the location of the
next element in the list.
Pre pList pointer to a valid list
fromWhere 0 to start at first element
dataPtrOut address of pointer to data
Post if more data, address of next node
Return true node located; false if end of list
*/
int traverse (LIST* pList,
int fromWhere,
void** dataPtrOut)
{
// Statements
if (pList->count == 0)
return 0;
if (fromWhere == 0)
{
//Start from first node
pList->pos = pList->head->forw;
*dataPtrOut = pList->pos->dataPtr;
return 1;
} // if fromwhere
else
{
// Start from current position
if (pList->pos->forw == pList->rear)
return 0;
else
{
pList->pos = pList->pos->forw;
*dataPtrOut = pList->pos->dataPtr;
return 1;
} // if else
} // if fromwhere else
} // traverse
/* ================== destroyList =================
Deletes all data in list and recycles memory
Pre List is a pointer to a valid list.
Post All data and head structure deleted
Return null head pointer
*/
LIST* destroyList (LIST* pList)
{
// Local Definitions
NODE* deletePtr;
// Statements
if (pList)
{
while (pList->count > 0)
{
// First delete data
free (pList->head->dataPtr);
// Now delete node
deletePtr = pList->head->forw;
pList->head = deletePtr->forw;
pList->count--;
free (deletePtr);
} // while
free (pList);
} // if
return NULL;
} // destroyList
/*
=================================================
============== Private Functions ================
=================================================
*/
/* ================== _search =================
Searches list and passes back address of node
containing target and its logical predecessor.
Pre pList pointer to initialized list
pPre pointer variable to predecessor
pLoc pointer variable to receive node
pArgu pointer to key being sought
Post pLoc points to first equal/greater key
-or- null if target > key of last node
pPre points to largest node < key
-or- null if target < key of first node
Return boolean true found; false not found
*/
static int _search (LIST* pList, NODE** pPre, NODE** pLoc, NODE** pSuc, void* pArgu)
{
// Macro Definition
//#define COMPARE ( ((* pList->compare) (pArgu, (*pLoc)->dataPtr)) )
#define COMPARE ( pList->compare(pArgu, (*pLoc)->dataPtr) )
//#define COMPARE_LAST ((* pList->compare) (pArgu, pList->rear->dataPtr))
#define COMPARE_LAST ( pList->compare(pArgu, pList->rear->prev->dataPtr) )
// Local Definitions
int result;
// Statements
*pPre = pList->head;
*pLoc = pList->head->forw;
*pSuc = pList->rear;
if (pList->count == 0)
return 0;
// Test for argument > last node in list
if ( COMPARE_LAST > 0)
{
*pPre = pList->rear->prev;
*pLoc = NULL;
*pSuc = pList->rear;
return 0;
} // if
while ( (result = COMPARE) > 0 )
{
// Have not found search argument location
*pPre = (*pLoc);
*pLoc = (*pLoc)->forw;
*pSuc = (*pLoc)->forw;
} // while
if (result == 0)
// argument found--success
return 1;
else
return 0;
} // _search
/* =================== _insert ==================
Inserts data pointer into a new node.
Pre pList pointer to a valid list
pPre pointer to data's predecessor
dataInPtr data pointer to be inserted
Post data have been inserted in sequence
Return boolean, true if successful,
false if memory overflow
*/
static int _insert (LIST* pList, NODE* pPre, NODE* pSuc,
void* dataInPtr)
{
// Local Definitions
NODE* pNew;
// Statements
if (!(pNew = (NODE*) malloc(sizeof(NODE))))
return 0;
pNew->dataPtr = dataInPtr;
pNew->forw = pSuc;
pNew->prev = pPre;
pPre->forw = pNew;
pSuc->prev = pNew;
(pList->count)++;
return 1;
} // _insert
/* ================= _delete ================
Deletes data from a list and returns
pointer to data to calling module.
Pre pList pointer to valid list.
pPre pointer to predecessor node
pLoc pointer to target node
dataOutPtr pointer to data pointer
Post Data have been deleted and returned
Data memory has been freed
*/
void _delete (LIST* pList, NODE* pPre,
NODE* pLoc, NODE* pSuc, void** dataOutPtr)
{
// Statements
*dataOutPtr = pLoc->dataPtr;
pPre->forw = pLoc->forw;
pSuc->prev = pLoc->prev;
(pList->count)--;
free (pLoc);
return;
} // _delete