Sub Linked List

Discussion in 'C++' started by Jeff Cheng, Jul 23, 2003.

  1. Jeff Cheng

    Jeff Cheng Guest

    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);

    }
     
    Jeff Cheng, Jul 23, 2003
    #1
    1. Advertising

  2. Jeff Cheng wrote:
    >
    > 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.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Jul 23, 2003
    #2
    1. Advertising

  3. "Jeff Cheng" <> wrote in message
    news:...
    > 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
     
    John Harrison, Jul 23, 2003
    #3
  4. 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?




    On 23 Jul 2003 01:02:20 -0700, (Jeff Cheng) wrote:

    >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
    them for anything -- use <iostream> instead.


    ># 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.
     
    Alf P. Steinbach, Jul 23, 2003
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Ritchey
    Replies:
    7
    Views:
    484
    emerth
    Jul 10, 2003
  2. fool
    Replies:
    14
    Views:
    512
    Barry Schwarz
    Jul 3, 2006
  3. joshd
    Replies:
    12
    Views:
    674
    John Carson
    Oct 2, 2006
  4. Ben
    Replies:
    2
    Views:
    898
  5. Lawrence D'Oliveiro

    Death To Sub-Sub-Sub-Directories!

    Lawrence D'Oliveiro, May 5, 2011, in forum: Java
    Replies:
    92
    Views:
    2,043
    Lawrence D'Oliveiro
    May 20, 2011
Loading...

Share This Page