Yea, I wasn't sure about the allocation thing either, is it best to just use malloc() before the while loop? And I guess it was easy to make global, probably not the best but I think global works.
Yea, I wasn't sure about the allocation thing either, is it best to just use malloc() before the while loop? And I guess it was easy to make global, probably not the best but I think global works.
In this case, the only function I see that needs malloc() is the InputRecord function, I took temp out of global and added that to ResetList and changed from using if to switch statements in main. To give an update on what my whole code looks like now this is it:
Code:#include <stdlib.h> #include <stdio.h> struct point { int x; //point x int y; //point y char label[21]; //label of 2 points struct point *ptrNext; // self referential pointer }; struct point *ptrFirst = NULL; struct point *ptrLast = NULL; struct point *ptrNew = NULL; int isEmptyList(struct point *ptrF); void PrintList(struct point *ptrF); void ResetList(struct point *ptrF, struct point *ptrL); void AddToBeginning(struct point *ptrF, struct point *ptrL); void AddToEnd(struct point *ptrF, struct point *ptrL); void InputRecord(struct point *ptrNew); // used by Add to interactively get the values from the user int isEmptyList(struct point *ptrF)//emptylist will determine if the list is empty { { if(ptrF==NULL) { return 0; } else return 1; } } //print list will print out everything void PrintList(struct point *ptrF) { struct point *pC = ptrF; while(pC != NULL) { printf("Label: %s\nx: %d y:%d\n", pC->label, pC->x, pC->y); pC = pC->ptrNext; // this is how a list is traversed } } //reset list will make everything equal to NULL void ResetList(struct point *ptrF, struct point *ptrL) { struct point *temp=NULL; while(ptrF!=NULL) { temp=ptrF->ptrNext; free(ptrF); ptrF=temp; } } //addtobeginning will add a number to the beginning void AddToBeginning(struct point *ptrF, struct point *ptrL) { if(ptrF==NULL) ptrF=ptrNew; InputRecord(ptrNew); ptrFirst->ptrNext=NULL; } //addtoend will add a number to the end void AddToEnd(struct point *ptrF, struct point *ptrL) { if(ptrF==NULL) ptrF = ptrNew; else { InputRecord(ptrNew); ptrL=ptrNew; } } //reads in input void InputRecord(struct point *ptrNew) { ptrNew=(struct point *)(malloc(sizeof(struct point))); printf("Please enter the 2 Data points(x and y):\n"); ptrFirst=ptrNew; if(ptrNew==NULL) printf("No more memory.\n"); else { scanf("%d%d",&ptrFirst->x, &ptrFirst->y); printf("Please enter the label:\n"); scanf("%s", ptrFirst->label); } } void main() { int empty=0;//helps determine if list is empty int input=1;//reads in user input while(input!=0) { printf( "1. Add a point at the END of the list.\n" "2. Add a point at the BEGINNING of the list.\n" "3. Is the list empty?\n" "4. Erase all points from the list (reset).\n" "5. Display the list.\n" "6. Save the list to a sequential file (reset/replace file contents)\n" "7. Read the list back from a sequential file\n" "(reset/replace current memory content)\n" "0. Exit\n\n" ); scanf("%d", &input); switch(input) { case 1: { AddToEnd(ptrFirst,ptrLast); } case 2: { AddToBeginning(ptrFirst,ptrLast); } case 3: { empty=isEmptyList(ptrFirst); if(empty==1) { printf("The list is not empty\n\n"); } else { printf("The list is empty\n\n"); } } case 4: { ResetList(ptrFirst,ptrLast); } case 5: { PrintList(ptrFirst); } case 6: { } case 7: { } default: { printf("Invalid entry, try again\n\n"); } } } }
Last edited by JamesD; 03-13-2011 at 10:07 AM.
You're moving in the right direction...
Now take the printout from case 3 and move it into the isemptylist function since that's the only place you use it. I always like to keep switch trees as nothing but a way to call functions. I seldom put code directly in a case statement. (You'll find out why the first time you have to debug one that goes wonkers on you...)
Your while(input != 0) should also be moved to a case 0 : at the top of the chain. It only needs to contain, return 0; The while loop then becomes simply while (1) This makes little apparent difference but it does prevent having to traverse the entire switch chain before discovering you want it to exit.
Also at the end of each case section you need to add a break statement... Absent that, case 1 will complete and fall directly into case 2... cascading down the entire chain.
added "break;" to all the cases, switched from void to int main and added the case 0. Thanks CommonTater. Can you see any other problems with it, as I have looked it over again and still can't find out why ResetList fails and it will only hold 1 set of values, when I scan in a second set it replaces and erases the first.
When you add a new record to the beginning of the list, you need to take the current start pointer (which points to the current first item) set it into your new record as the pointer to the next item and then make the start pointer point to your new item.
Similarly when adding to the end of the list you need to traverse the list, find the item with the null pointer (marking end of list) and set it's value to point to your new record. The pointer to the next item in your record then becomes NULL signalling the new end of list.
Personally I think linked lists are icky things, I seldom use them if I can get out of it, but it's all about making absolutely certain that each record points to the next one in the chain.
I won't be able to work on it until later today but you helped a bunch. Thanks and I will try to fix up where they point to.
These are my codes for adding to the beginning:
Code:case 2: { AddToBeginning(ptrFirst,ptrLast); break; }Code:void AddToBeginning(struct point *ptrF, struct point *ptrL) { InputRecord(ptrNew); ptrNew->ptrNext=NULL; if(ptrF==NULL) ptrF=ptrNew; if(ptrF!=NULL) ptrNew->ptrNext; ptrL->ptrNext; }In add to beginning I use ptrNew to get the input, and point it to ptrNext, the next pointer.Code:void InputRecord(struct point *ptrNew) { ptrNew=(struct point *)(malloc(sizeof(struct point))); printf("Please enter the 2 Data points(x and y):\n"); ptrFirst=ptrNew; if(ptrNew==NULL) printf("No more memory.\n"); else { scanf("%d%d",&ptrNew->x, &ptrNew->y); printf("Please enter the label:\n"); scanf("%s", ptrNew->label); } }
Then I verify if ptrF is NULL if it is, it will point to ptrNew(the now first pointer). and if not point ptrNew to the next pointer and update ptrL to the last position. However this fails when I use it, can someone explain?
In InputRecord you should not set ptrFirst... Stay on task, create the new record and return a pointer to it.
In AddToBeginning again stay on task, here you only manipulate the pointers...Code:struct point *InputRecord ( void ) { struct point *ptrN= malloc(sizeof(struct point)); if(ptrN == NULL) { printf("No more memory.\n"); exit(1); } // this is a fatal error so exit if it happens // get new information printf("Please enter the 2 Data points(x and y):\n"); scanf("%d%d",&ptrN->x, &ptrN->y); printf("Please enter the label:\n"); scanf("%s", ptrN->label); return ptrN; } // return pointer to new struct
It's late here, I'm sure there's a minor error or two in there, but this should give you some idea.Code:void AddToBeginning(struct point *ptrF) { struct point *temp = ptrf; // save pointer to first record ptrF = InputRecord(); // get pointer to new first record ptrF->ptrNext = temp; } // next in new record points to saved
Last edited by CommonTater; 03-14-2011 at 10:25 PM. Reason: minor fix in add to beginning
How does the prototype look when using struct, I have:
struct point InputRecord(void);
however I think its trying to read it in as a declaration.
Got addtobeginning and input record set now, and I think reset list is working, just gotta work on printlist
How does this not work, it has a new pointer which points to the first and while it isn't null it prints out and then points to the next, anyone see what's wrong here?Code:void PrintList(struct point *ptrF) { struct point *pC = ptrF; while(pC != NULL) { printf("Label: %s\nx: %d y:%d\n\n", pC->label, pC->x, pC->y); pC = pC->ptrNext; // this is how a list is traversed PrintList(struct point *pC) } }
Last edited by JamesD; 03-14-2011 at 01:40 PM.
Why are you recursively calling PrintList? Just call it once, and use a loop. If you are using recusion, you don't need the while loop. You just need an if check. Recursion is just another way to loop. Use one or the other here, not both.
Quzah.
Hope is the first step on the road to disappointment.
Assume it's the exact same but without recursion, when called nothing will print out, and that's got me confused.