Sub Linked List

J

Jeff Cheng

Can anybody help to trace the runtime error for the following code
about sub-Linked list.

Thank you,


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

typedef char *CategoryType;
typedef char *ItemType;
typedef char *CodeType;
typedef int QtyType;

typedef struct node_item {
ItemType ItemDesc;
CodeType CodeNo;
QtyType Quantity;
node_item *NextItemLink;
} items;

typedef struct node_cat {
node_item *ItemLink;
CategoryType CatData;
node_cat *CatLink;
} category;


typedef category *CatPtr;
//typedef items *ItemLink;
typedef items *ItemLink;

void Initialise (CatPtr *L) {
*L = NULL;
}

// this is to add category
void AddCatNode (CatPtr *L, CategoryType x) {
CatPtr p, q;

p=(CatPtr) malloc (sizeof(category));
p->CatData = x;
p->CatLink = NULL;
if (*L == NULL)
*L = p;
else {
q = *L;
while (q->CatLink!=NULL)
q=q->CatLink;
q->CatLink = p;
}
}

// this is to add item
void AddItemNode (ItemLink *L, ItemType x, CodeType y, QtyType z) {
ItemLink p, q;

p=(ItemLink) malloc (sizeof(items));
p->ItemDesc = x;
p->CodeNo = y;
p->Quantity = z;
p->NextItemLink = NULL;
if (*L == NULL)
*L = p;
else {
q = *L;

//while (q->NextItemLink!=NULL)
// q=q->NextItemLink;
//q->NextItemLink = p;
}
}

//cat search
CatPtr SearchCatList (CatPtr L, CategoryType x) {
CatPtr p;
p = L;
while (p!=NULL) {
if (x == p->CatData)
return p;
else
p=p->CatLink;
}
return p;
}

//item search
ItemLink SearchItemList (ItemLink L, ItemType x) {
ItemLink p;
p = L;
while (p!=NULL) {
if (x == p->CodeNo)
return p;
else
p=p->NextItemLink;
}
return p;
}

//item display
void DisplayItemList (ItemLink L) {
ItemLink p;

for (p=L; p!=NULL; p=p->NextItemLink) {
printf("%s\n", p->ItemDesc);
printf("%s\n", p->CodeNo);
printf("%d\n", p->Quantity);
}
}



void main() {
CatPtr CatList,p;
ItemLink ItemList, i;
int choice, z;
char yn;
char *x, *y;


Initialise (&CatList);

do {

printf ("Main Menu\n");
printf ("1. Add Record\n");
printf ("2. Search\n");
printf ("3. Print\n");
printf ("9. Exit\n");
printf("\nPlease enter your choice> ");
scanf ("%d", &choice);

switch (choice) {
case 1:
printf ("Please select what you want to add\n");
printf ("1. Add Category\n");
printf ("2. Add Item\n");
printf ("Please enter your choice> ");
scanf ("%d", &choice);

// this is to add new category
if (choice == 1) {
printf ("Please key in New Category> ");
scanf ("%s", &x);
AddCatNode (&CatList, x);
}

// this is to add new item
if (choice == 2) {
printf ("Please key in Category> ");
scanf ("%s", &x);
p= SearchCatList (CatList, x);
if (p==NULL)
printf ("Category not found\n");
else {
printf ("Please enter the New Item> ");
scanf ("%s", &x);
printf ("Please enter the New Code> ");
scanf ("%s", &y);
printf ("Please enter the Quantity> ");
scanf ("%d", &z);
AddItemNode (&ItemList, x, y ,z);
}
}

break;


case 2:
printf ("Please Enter Category> ");
scanf("%s", &x);
p = SearchCatList (CatList, x);

printf ("Please Enter Code No> ");
scanf("%s", &y);
i = SearchItemList (ItemList, y);

if (i==NULL)
printf ("No such item");
else {
printf("%s", i->ItemDesc);
printf("%s", i->CodeNo);
printf("%d", i->Quantity);
}
break;

case 3:
printf ("Please enter your Category> ");
scanf ("%s", &x);

DisplayItemList (ItemList);
break;


//int tem;
//tem = 1;
//while (tem < 100000) {
// tem++;
printf("%s", &x);
//}


}
}while (choice !=9);

}
 
K

Karl Heinz Buchegger

Jeff said:
Can anybody help to trace the runtime error for the following code
about sub-Linked list.

How about making your runtime error reproducable in the first place.
That means: write a new main, which is not dependent on user input
and is as short as possible.

If you start with that and step through the code you actually
*might* find the problem by yourself.

That's always the first thing in fighting a bug: make it reproducable!
Thank you,

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

typedef char *CategoryType;
typedef char *ItemType;
typedef char *CodeType;
typedef int QtyType;

typedef struct node_item {
ItemType ItemDesc;
CodeType CodeNo;
QtyType Quantity;
node_item *NextItemLink;
} items;

typedef struct node_cat {
node_item *ItemLink;
CategoryType CatData;
node_cat *CatLink;
} category;

typedef category *CatPtr;
//typedef items *ItemLink;
typedef items *ItemLink;

void Initialise (CatPtr *L) {
*L = NULL;
}

// this is to add category
void AddCatNode (CatPtr *L, CategoryType x) {
CatPtr p, q;

p=(CatPtr) malloc (sizeof(category));

don't cast the return value of malloc. It may hide a
serious bug!
p->CatData = x;

This just copies the pointer! Are you aware of that and have
you thought it through if this is really what you want to do?

[big snip while checking this ]
void main() {

main returns int. Always!
CatPtr CatList,p;
ItemLink ItemList, i;
int choice, z;
char yn;
char *x, *y;

x is a pointer to characters.

[snip]
if (choice == 1) {
printf ("Please key in New Category> ");
scanf ("%s", &x);

Boom!
Where is the memory where scanf should write to?
Are you sure that the memory reserved for a character pointer
can hold your string?

Also: you promise to scanf by specifying %s, that the second argument will
be a character pointer, yet you pass a pointer to a character pointer. Those
don't fit.


eg.
x = malloc( 80 ); // allocate room for 80 characters
scanf( "%s", x );


I'll stop here.
May I suggest that before you continue your studies on data structures, that you
make yourself familiar with the way string handling works in C? There are lots
of pitfalls in that topic and it seems you trapped in every single on of them.
 
J

John Harrison

Jeff Cheng said:
Can anybody help to trace the runtime error for the following code
about sub-Linked list.

Thank you,

What input produces the bug? Please, do a little bit of work yourself, to
help the group help you.

john
 
A

Alf P. Steinbach

As Karl and John have already noted you need to do some
work yourself and provide the details.

However, as to the C _code_, why do you post C code in a
C++ group?




Can anybody help to trace the runtime error for the following code
about sub-Linked list.

Thank you,


# include <stdio.h>

That should be

#include <cstdio>

_if_ that header was required. But these facilities are not, in
general, type safe. So at your current level you should not use
# include <stdlib.h>

That should be


#include <cstdlib>


_if_ that header were required (which it isn't).

typedef char *CategoryType;
typedef char *ItemType;
typedef char *CodeType;

Yes it is a good idea to name things. No it isn't a good
idea to represent these types as the same type. If they have
different functionality, e.g. restrictions on the set of
valid values, capture that by using proper classes.

Also, it's absolutely not a good idea to use char* even where
you only need a string of characters.

Use std::string instead, so as to avoid allocation and
deallocation bugs.


typedef int QtyType;

Yes it is a good idea to name things. No it isn't a good
idea to hide the direct representation as int behind a
name. Use a class, or use plain int.


typedef struct node_item {
ItemType ItemDesc;
CodeType CodeNo;
QtyType Quantity;
node_item *NextItemLink;
} items;

In C++ that would be


struct node_item {
itemType ItemDesc;
CodeType CodeNo;
QtyType Quantity;
node_item *NextItemLink;
};

typedef node_item items;


But what is it you imagine that you need the typedef for?

It's _not_ a good idea to introduce aliases for type names.



typedef struct node_cat {
node_item *ItemLink;
CategoryType CatData;
node_cat *CatLink;
} category;
Ditto.




typedef category *CatPtr;
//typedef items *ItemLink;
typedef items *ItemLink;

void Initialise (CatPtr *L) {
*L = NULL;
}

Use a constructor for initialization.


// this is to add category
void AddCatNode (CatPtr *L, CategoryType x) {
CatPtr p, q;

p=(CatPtr) malloc (sizeof(category));

Don't use malloc. In C++ use 'new'.

p->CatData = x;
p->CatLink = NULL;
if (*L == NULL)
*L = p;
else {
q = *L;
while (q->CatLink!=NULL)
q=q->CatLink;
q->CatLink = p;
}
}

// this is to add item
void AddItemNode (ItemLink *L, ItemType x, CodeType y, QtyType z) {
ItemLink p, q;

p=(ItemLink) malloc (sizeof(items));
p->ItemDesc = x;
p->CodeNo = y;
p->Quantity = z;
p->NextItemLink = NULL;
if (*L == NULL)
*L = p;
else {
q = *L;

//while (q->NextItemLink!=NULL)
// q=q->NextItemLink;
//q->NextItemLink = p;
}
}

Indentation, indentation, indentation.



//cat search
CatPtr SearchCatList (CatPtr L, CategoryType x) {
CatPtr p;
p = L;
while (p!=NULL) {
if (x == p->CatData)
return p;
else
p=p->CatLink;
}
return p;
}

//item search
ItemLink SearchItemList (ItemLink L, ItemType x) {
ItemLink p;
p = L;
while (p!=NULL) {
if (x == p->CodeNo)
return p;
else
p=p->NextItemLink;
}
return p;
}

//item display
void DisplayItemList (ItemLink L) {
ItemLink p;

for (p=L; p!=NULL; p=p->NextItemLink) {
printf("%s\n", p->ItemDesc);
printf("%s\n", p->CodeNo);
printf("%d\n", p->Quantity);
}
}



void main() {

Invalid in both C and C++. Should be


int main()




CatPtr CatList,p;
ItemLink ItemList, i;
int choice, z;
char yn;
char *x, *y;


Initialise (&CatList);

do {

printf ("Main Menu\n");
printf ("1. Add Record\n");
printf ("2. Search\n");
printf ("3. Print\n");
printf ("9. Exit\n");
printf("\nPlease enter your choice> ");
scanf ("%d", &choice);

switch (choice) {
case 1:
printf ("Please select what you want to add\n");
printf ("1. Add Category\n");
printf ("2. Add Item\n");
printf ("Please enter your choice> ");
scanf ("%d", &choice);

// this is to add new category
if (choice == 1) {
printf ("Please key in New Category> ");
scanf ("%s", &x);
AddCatNode (&CatList, x);
}

// this is to add new item
if (choice == 2) {
printf ("Please key in Category> ");
scanf ("%s", &x);
p= SearchCatList (CatList, x);
if (p==NULL)
printf ("Category not found\n");
else {
printf ("Please enter the New Item> ");
scanf ("%s", &x);
printf ("Please enter the New Code> ");
scanf ("%s", &y);
printf ("Please enter the Quantity> ");
scanf ("%d", &z);
AddItemNode (&ItemList, x, y ,z);
}
}

break;


case 2:
printf ("Please Enter Category> ");
scanf("%s", &x);
p = SearchCatList (CatList, x);

printf ("Please Enter Code No> ");
scanf("%s", &y);
i = SearchItemList (ItemList, y);

if (i==NULL)
printf ("No such item");
else {
printf("%s", i->ItemDesc);
printf("%s", i->CodeNo);
printf("%d", i->Quantity);
}
break;

case 3:
printf ("Please enter your Category> ");
scanf ("%s", &x);

DisplayItemList (ItemList);
break;


//int tem;
//tem = 1;
//while (tem < 100000) {
// tem++;
printf("%s", &x);
//}


}
}while (choice !=9);

}

The number of lines in main is unacceptable. Keep it down to
something that can be grokked at a glance.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top