Sub Linked List

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jeff Cheng

    Sub Linked List

    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(categor y));
    p->CatData = x;
    p->CatLink = NULL;
    if (*L == NULL)
    *L = p;
    else {
    q = *L;
    while (q->CatLink!=NUL L)
    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("\nPleas e 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);

    }
  • Karl Heinz Buchegger

    #2
    Re: Sub Linked List



    Jeff Cheng wrote:[color=blue]
    >
    > Can anybody help to trace the runtime error for the following code
    > about sub-Linked list.[/color]

    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!
    [color=blue]
    >
    > 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(categor y));[/color]

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

    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 ]
    [color=blue]
    >
    > void main() {[/color]

    main returns int. Always!
    [color=blue]
    > CatPtr CatList,p;
    > ItemLink ItemList, i;
    > int choice, z;
    > char yn;
    > char *x, *y;[/color]

    x is a pointer to characters.

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

    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
    kbuchegg@gascad .at

    Comment

    • John Harrison

      #3
      Re: Sub Linked List


      "Jeff Cheng" <elkenjeff@hotm ail.com> wrote in message
      news:416984df.0 307230002.4d6da f84@posting.goo gle.com...[color=blue]
      > Can anybody help to trace the runtime error for the following code
      > about sub-Linked list.
      >
      > Thank you,
      >
      >[/color]

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

      john


      Comment

      • Alf P. Steinbach

        #4
        Re: Sub Linked List

        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, elkenjeff@hotma il.com (Jeff Cheng) wrote:
        [color=blue]
        >Can anybody help to trace the runtime error for the following code
        >about sub-Linked list.
        >
        >Thank you,
        >
        >
        ># include <stdio.h>[/color]

        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.

        [color=blue]
        ># include <stdlib.h>[/color]

        That should be


        #include <cstdlib>


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

        [color=blue]
        >typedef char *CategoryType;
        >typedef char *ItemType;
        >typedef char *CodeType;[/color]

        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.


        [color=blue]
        >typedef int QtyType;[/color]

        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.


        [color=blue]
        >typedef struct node_item {
        > ItemType ItemDesc;
        > CodeType CodeNo;
        > QtyType Quantity;
        > node_item *NextItemLink;
        >} items;[/color]

        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.



        [color=blue]
        >typedef struct node_cat {
        > node_item *ItemLink;
        > CategoryType CatData;
        > node_cat *CatLink;
        >} category;[/color]

        Ditto.



        [color=blue]
        >typedef category *CatPtr;
        >//typedef items *ItemLink;
        >typedef items *ItemLink;
        >
        >void Initialise (CatPtr *L) {
        > *L = NULL;
        >}[/color]

        Use a constructor for initialization.


        [color=blue]
        >// this is to add category
        >void AddCatNode (CatPtr *L, CategoryType x) {
        > CatPtr p, q;
        >
        > p=(CatPtr) malloc (sizeof(categor y));[/color]

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

        [color=blue]
        > p->CatData = x;
        > p->CatLink = NULL;
        > if (*L == NULL)
        > *L = p;
        > else {
        > q = *L;
        > while (q->CatLink!=NUL L)
        > 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;
        > }
        > }[/color]

        Indentation, indentation, indentation.



        [color=blue]
        >//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() {[/color]

        Invalid in both C and C++. Should be


        int main()




        [color=blue]
        > 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("\nPleas e 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);
        >
        >}[/color]

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


        Comment

        Working...