Help with getting input with linklist in a loop

Discussion in 'C' started by thamiz, Sep 14, 2008.

  1. thamiz

    thamiz New Member

    Joined:
    Apr 16, 2008
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    Hi there, i am new to using link-list.....

    Code:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>
    #include <ctype.h>
    
    typedef struct ingredient Ingredient;
    enum quantity_type {
       weight,
       volume,
       piece,
    };
    struct ingredient {
    char *name;
    int quantity;
    enum quantity_type type;
    Ingredient *next;
    };
    
    the user to has to enter a list of ingredients at a time. The selection may be re-entered to add to the already stored list of ingredients.

    the list has to be in a loop until an empty string is entered in to te char name;
    any one willing to help me out
     
  2. hbilling

    hbilling New Member

    Joined:
    Aug 30, 2008
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    0
    Hi,
    You could use a system which allocates memory for a new node in the Linked List only if it passes your condition. ie. If the name entered is an empty string, then just dont allocate memory for a new node.

    ......
    char name_str[20]; // Its just hardcoded here for convenience

    for(;;) {
    printf("\n Enter the name\n");
    scanf("%s", name_str);
    if(strcmp(name_str, '')) {
    break; <<<<<< Here u break off from the loop if name is a null String
    }

    ......
    // Similarly get the other elements also from the user

    //if all is fine , u actually allocate memory for the node using malloc and add it to the list using ur API's.

    }

    HTH. If not i can explain in detail :)
     
  3. hbilling

    hbilling New Member

    Joined:
    Aug 30, 2008
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    0
    sorry abt the smiley above. its actually an unconditional for loop. :)
     
  4. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Where are you stuck? The code you posted doesn't have a main function...
    Are you hoping we'll write the code for you?
     
  5. hbilling

    hbilling New Member

    Joined:
    Aug 30, 2008
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    0
    Hi xpi0t0s,

    First of all I assume ur comment was meant for thamiz. If so, I think he/she just wanted an idea, which i guess i gave in my solution:) .
    If its understood by him/her, its great! Having said that, i think having a full code with a main function is always easier to answer on.

    Regards,
    Harneet
     
  6. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    yep, the comment was aimed at thamiz.
     
  7. thamiz

    thamiz New Member

    Joined:
    Apr 16, 2008
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    hi
    yeah sorry about not including the main function.
    but i want to know, can we have a stsuct within a struct and how would u implement it
    eg if we use the above code
    i can add and print from the following structure
    Code:
    struct ingredient {
    char *name;
    int quantity;
    enum quantity_type type;
    Ingredient *left;
    Ingredient *right;
    };
    
    Now i want to make a stucture called Recipe
    Srtuct recipe {
    char* recipename;
    //i need to include the struct for ingredients here;
    recipe *left;
    recipe *right;
    };
    any body know how i can do this
    thank in advance
    cheers:
     
  8. thamiz

    thamiz New Member

    Joined:
    Apr 16, 2008
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    soory guys
    i forgot use the correct standard
    hi
    yeah sorry about not including the main function.
    but i want to know, can we have a stsuct within a struct and how would u implement it
    eg if we use the above code
    i can add and print from the following structure

    Code:

    struct ingredient {
    char *name;
    int quantity;
    enum quantity_type type;
    Ingredient *left;
    Ingredient *right;
    };
    Now i want to make a stucture called Recipe
    Code:
    Srtuct recipe {
    char* recipename;
    //i need to include the struct for ingredients here;
    recipe *left;
    recipe *right;
    };
    
    any body know how i can do this
    thank in advance
    cheers:
     
  9. thamiz

    thamiz New Member

    Joined:
    Apr 16, 2008
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    is there any one willing to have a look at my code, and see where i am going wrong..
    but i have to send it to u personally because it is kind of a homework thing.
     
  10. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Embedded/nested structures are fine:
    Code:
    struct recipe {
    char* recipename;
    struct {
    recipe *left;
    recipe *right;
    } links;
    } R;
    
    Then refer to R.recipename, R.links.left, R.links.right.

    Sorry, post the code here, that's how the forum works, and we all get to look at it, which is useful if, say, I don't understand something it's doing but someone else does. If it's your homework and it's OK to post it on the internet to get others to fix it then that shouldn't be a problem. If it's not OK to post it on the internet, well you shouldn't be barking up this tree.

    You could simplify the code, creating a small testcase that isolates the problematic stuff from the rest, I don't see any teacher objecting to that as you'd obviously not be plagiarising (which is generally considered a major sin in academic circles).
     
  11. thamiz

    thamiz New Member

    Joined:
    Apr 16, 2008
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    Here is the main code
    Code:
    printf("Name of Recipe: ");
                    fgets(recipename,29,stdin);
                    trim(recipename);
                    for(;;){
                       printf("Name of Ingredient: ");
                       fgets(name,29,stdin);
                       trim(name);
                       if(!strcmp(name,"")){
                          enter=0;
                          break;
                       }
                       printf("Quantity: ");
                       fgets(buff,29,stdin);
                       sscanf(buff,"%d",&quantity);
                       printf("Q_type: ");
                       fgets(buff,29,stdin);
                       sscanf(buff,"%c",&type);
                       rlocation = Recipesearch_tree(rtree, name);
                       if (!rlocation) {
                          /* not in tree, so insert the new word */
                          rtree = Rinsert_ingredient_order(rtree, name,quantity,type);
                       }
                   }
    
    then here is the search function
    Code:
    Recipe *Recipesearch_tree(Recipe *rtree, char *search_name) {
       int compare;
       if(rtree == NULL) {
          return NULL;
       }
       else {
          if((compare = strcmp(search_name, rtree->recipename)) == 0) {
             return rtree; // node found
          }
          else if (compare < 0) {
             return Recipesearch_tree(rtree->left, search_name);
          }
          else {
             return Recipesearch_tree(rtree->right, search_name);
          }
       }
    }
    
    and here is insert function for recipe
    Code:
    Recipe *rinsert_ingredient_order(Recipe *rtree, char *name,int quantity,char type){
       Ingredient *tree1=NULL;
       if (rtree == NULL) {
          rtree =(Recipe*)malloc(sizeof(Recipe));
          assert(rtree!=NULL);
          rtree->recipename =(char *)malloc(strlen(name)+1);
          while(tree1=insert_ingredient_order(tree1,name,quantity,type)=!NULL){
             tree1=nsert_ingredient_order(tree1,name,quantity,type);
          }
         return rtree;
    }
    
    thanks in advance
     
  12. thamiz

    thamiz New Member

    Joined:
    Apr 16, 2008
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    Here is the full code
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include <ctype.h>
    typedef enum {
       weight,
       volume,
       piece,
    }quantity_type;
    typedef struct ingredient Ingredient;
    struct ingredient{
    	char* name;                          //Name of Ingredient
    	int quantity;                        //Quantity of the ingredient
    	quantity_type Qtype;
    	Ingredient* left;                    // left subtree of node
     Ingredient* right;                   // Right subtree of node
    };
    
    typedef struct recipe Recipe;
    struct recipe {
      char* recipename;
      Ingredient *list;
      Recipe *left;
      Recipe *right;
    };
    /* prototypes for the Binary Search Tree operations */
    Ingredient *search_tree(Ingredient *tree, char *search_name);
    Ingredient *insert_ingredient_order(Ingredient *tree, char *new_name,int quantity);
    Recipe *Recipesearch_tree(Recipe *rtree, char *search_name);
    Recipe *Rinsert_ingredient_order(Recipe *rtree, char *name,int quantity,char type);
    void print_out_ingredient(Ingredient *tree);
    void print_out_recipe(Recipe *rtree);
    void free_ingredient(Ingredient *tree);
    void free_recipe(Recipe *rtree);
    void printmenu(void);
    void trim(char *oops);
    
    /* prototypes for the Binary Search Tree operations Ends*/
    
    /*The Main Function*/
    int main(int argc,char* argv[]) {
        Ingredient *tree = NULL;
        Ingredient *location;
        Recipe *rtree=NULL;
        Recipe *rlocation;
        char choice=0;
        int quantity;
        char name[30];
        char buff[30];
        char recipename[30];
        char type;
        int enter = 1;
        while(enter ==1){
            printmenu();
            while((choice = getchar()) != '\n'){
              choice=toupper(choice);
              getchar();
              switch(choice){
                 case 'R':
                    printf("Name of Recipe: ");
                    fgets(recipename,29,stdin);
                    trim(recipename);
                    for(;;){
                       printf("Name of Ingredient: ");
                       fgets(name,29,stdin);
                       trim(name);
                       if(!strcmp(name,"")){
                          enter=0;
                          break;
                       }
                       printf("Quantity: ");
                       fgets(buff,29,stdin);
                       sscanf(buff,"%d",&quantity);
                       printf("Q_type: ");
                       fgets(buff,29,stdin);
                       sscanf(buff,"%c",&type);
                       rlocation = Recipesearch_tree(rtree, name);
                       if (!rlocation) {
                          /* not in tree, so insert the new word */
                          rtree = Rinsert_ingredient_order(rtree, name,quantity,type);
                       }
                   }
                    break;
                 case 'I':
                    for(;;){
                       printf("Name of Ingredient: ");
                       fgets(name,29,stdin);
                       trim(name);
                        if(!strcmp(name,"")){
                          enter=0;
                          break;
                       }
                       printf("Quantity: ");
                       fgets(buff,29,stdin);
                       sscanf(buff,"%d",&quantity);
                       printf("Q_type: ");
                       fgets(buff,29,stdin);
                       sscanf(buff,"%c",&type);
                       if (type==('P' || 'p')) {
                          quantity_type Qtype=piece;
                       }
                       else if(type==('W' || 'w')){
                          quantity_type Qtype=weight;
                       }
                       else if(type==('V' || 'v')){
                          quantity_type Qtype=volume;
                       }
                       location = search_tree(tree, name);
                       if (!location) {
                          /* not in tree, so insert the new word */
                          tree = insert_ingredient_order(tree, name,quantity);
                       }
                       else {
                          /*If already in tree, then add the quantity */
                          location->quantity=location->quantity + quantity;
                       }
                    }
                    break;
                 case 'C':
                    print_out_recipe(rtree);
                    break;
                 case 'G':
                    print_out_ingredient(tree);
                    break;
                 case 'S':
                    break;
                 default:
                    printf("Invalid option selected\n");
                    printf("please enter a valid choice\n");
              }
             printf("\n");
             printmenu();
           }
        }
        free_ingredient(tree);
        tree=NULL;
        free_recipe(rtree);
        rtree=NULL;
        return 0;
    }
    /*Search Node*/
    Ingredient *search_tree(Ingredient *tree, char *search_name) {
        int compare;
        if(tree == NULL) {
          return NULL;
        }
        else {
          if((compare = strcmp(search_name, tree->name)) == 0) {
            return tree; // node found
          }
          else if (compare < 0) {
            return search_tree(tree->left, search_name);
          }
          else {
            return search_tree(tree->right, search_name);
          }
        }
    }
    /*Insert Ingredients in Order*/
    Ingredient *insert_ingredient_order(Ingredient *tree, char *new_name,int quantity){
    	if (tree == NULL) {
    		tree =(Ingredient*)malloc(sizeof(Ingredient));
    		assert(tree!=NULL);
    		tree->name =(char *)malloc(strlen(new_name)+1);
    		strcpy(tree->name, new_name);
    		tree->quantity =quantity;
    		tree->left = tree->right = NULL;
    	}
    	else if (strcmp(new_name, tree->name) < 0) {
    		tree->left = insert_ingredient_order(tree->left, new_name,quantity);
    	}
    	else {
    		tree->right = insert_ingredient_order(tree->right, new_name,quantity);
    	}
    	return tree;
    }
    void print_out_ingredient(Ingredient *tree) {
       if(tree) {
          print_out_ingredient(tree->left);
          printf("%4d%-29s\n",tree->quantity,tree->name);
          print_out_ingredient(tree->right);
        }
    }
    void free_ingredient(Ingredient *tree){
       if(tree) {
         free_ingredient(tree->left);
         free_ingredient(tree->right);
         free(tree->name);
         free(tree);
       }
    }
    void printmenu(void){
       printf("I R O N  C H E F\n");
       printf("Add <R>ecipe\n");
       printf("Add <I>ngredients\n");
       printf("List re<C>ipes\n");
       printf("List in<G>redients\n");
       printf("<S>uggest a dish\n");
       printf("\n");
       printf("Selection: ");
    }
    void trim(char *oops){
       while(*oops){
          if(*oops=='\n'){
             *oops='\0';
          }
          oops++;
       }
    }
    /* Search Node For Recipe */
    Recipe *Recipesearch_tree(Recipe *rtree, char *search_name) {
       int compare;
       if(rtree == NULL) {
          return NULL;
       }
       else {
          if((compare = strcmp(search_name, rtree->recipename)) == 0) {
             return rtree; // node found
          }
          else if (compare < 0) {
             return Recipesearch_tree(rtree->left, search_name);
          }
          else {
             return Recipesearch_tree(rtree->right, search_name);
          }
       }
    }Recipe *rinsert_ingredient_order(Recipe *rtree, char *name,int quantity,char type){
       Ingredient *tree1=NULL;
       if (rtree == NULL) {
          rtree =(Recipe*)malloc(sizeof(Recipe));
          assert(rtree!=NULL);
          rtree->recipename =(char *)malloc(strlen(name)+1);
          while(tree1=insert_ingredient_order(tree1,name,quantity,type)=!NULL){
             tree1=nsert_ingredient_order(tree1,name,quantity,type);
          }
         return rtree;
    }
    /* Insert node in order for Recipe */
    
    /*  print out Recipe*/
    void print_out_recipe(Recipe *rtree) {
       if(rtree) {
          print_out_recipe(rtree->left);
          //printf("%4d%-29s\n",rtree->quantity,rtree->name);
          print_out_recipe(rtree->right);
       }
    }
    void free_recipe(Recipe *rtree){
       if(rtree) {
          free_recipe(rtree->left);
          free_recipe(rtree->right);
          free(rtree->recipename);
          free(rtree);
       }
    }
    
     
  13. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    OK, and what's the problem? Is it working fine and you just want a general review? Is it doing something wrong and you don't know how to fix it? What is it doing wrong? What _exact_ line of code is going wrong? What were you expecting it to do?

    It's like taking your car to the garage. You've done the equivalent of "Here's my car."
    Mechanic's now looking at you and going "yeah, and?"
     
  14. thamiz

    thamiz New Member

    Joined:
    Apr 16, 2008
    Messages:
    11
    Likes Received:
    0
    Trophy Points:
    0
    umm the add add ingredients part works bt foe some reason, when i wrote the commad for add recipe, it won't compile come up with an error:
    C:\Documents and Settings\Administrator\My Documents\v15.c||In function `Recipe* rinsert_ingredient_order(Recipe*, char*, int, char)':|
    C:\Documents and Settings\Administrator\My Documents\v15.c|161|error: too many arguments to function `Ingredient* insert_ingredient_order(Ingredient*, char*, int)'|
    C:\Documents and Settings\Administrator\My Documents\v15.c|234|error: at this point in file|
    C:\Documents and Settings\Administrator\My Documents\v15.c|234|warning: converting to non-pointer type `bool' from NULL|
    C:\Documents and Settings\Administrator\My Documents\v15.c|234|error: non-lvalue in assignment|
    C:\Documents and Settings\Administrator\My Documents\v15.c|235|error: `nsert_ingredient_order' was not declared in this scope|
    C:\Documents and Settings\Administrator\My Documents\v15.c|242|error: a function-definition is not allowed here before '{' token|
    C:\Documents and Settings\Administrator\My Documents\v15.c|249|error: a function-definition is not allowed here before '{' token|
    C:\Documents and Settings\Administrator\My Documents\v15.c|256|error: expected `}' at end of input|
    ||=== Build finished: 7 errors, 1 warnings ===|
     
  15. oogabooga

    oogabooga New Member

    Joined:
    Jan 9, 2008
    Messages:
    115
    Likes Received:
    11
    Trophy Points:
    0
    Hilarious!
    Or like going to the doctor and just staring at him.
    Keep it up long enough and he'll send you to a psychiatrist!
     
  16. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Seems fairly self explanatory. The first error is "error: too many arguments to function",
    the call is insert_ingredient_order(tree1, name, quantity, type) (i.e. 4 arguments)
    the function called is insert_ingredient_order(Ingredient *tree, char *new_name,int quantity) (i.e. 3 arguments).

    Is the problem then that you don't understand what "too many arguments to function" means?

    The while loop is otherwise a bit bizarre. Do you really mean to call insert_ingredient_order() twice for each iteration? What if the one in the braces returns NULL but the one in the while test doesn't?

    Check order of precedence. A = B != C means assign to A the boolean value that is the result of the comparison of B not-equal-to C, or using brackets to show the order of precedence: A = (B != C). This is why you get the warning "warning: converting to non-pointer type `bool' from NULL" -- it's a warning because the code isn't necessarily wrong; you can compare something and assign the result to something else. What you might mean is ((A=B)!=C), i.e. assign THEN compare with NULL.

    I'm not sure that =! means the same as !=; it might mean "assign the logical inverse" rather than "not equals". Use the common ordering for clarity, i.e. if =! == !=, use !=. Similarly if <>==><, use <>. Be a smart alec when you're smart, not before.

    The error about nsert_ingredient_order should be obvious, but if "too many arguments" isn't obvious..... Count the i's.

    The braces don't match in rinsert_ingredient_order(), that's why you get "error: a function-definition is not allowed here before '{' token". Always line up braces while you're learning; you can start to put them in silly places such as on the same line as the test once you stop making mistakes like this.
    With lining up not only is the missing closing brace obvious but you probably wouldn't have made that mistake in the first place:
    Code:
    }  // Start a new function on a new line, i.e. ...
    
    Recipe *rinsert(...) // ... HERE, not on the same line as the closing 
    brace of the previous function
    { // Place the opening brace of rinsert HERE, not on the line above.
      Ing *t=0;
      if (rtree==NULL)
      { // Brace goes HERE, not on the line above
        rtree=whatever;
        while (stuff!=NULL)
        { // Brace goes HERE, not on the line above
          stuff; // strange, to duplicate the stuff in the while test AND
     in the loop.
        } Closing brace for the while
        return DANGER WILL ROBINSON.  Because we're indenting correctly 
    and know the final return should be 2 spaces in rather than 4, it should
    be immediately obvious that we're in the wrong place.
      } // This is what you think is the closing brace of the function, but 
    proper indentation shows clearly that it isn't.
    
    void print()  // You can't have nested functions.  Because rinsert 
    isn't complete this function is being declared INSIDE 
    function rinsert().
    {
      // etc.
    
     
    Last edited: Sep 20, 2008
    shabbir likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice