Thread: linked list again

  1. #1
    life is a nightmare
    Join Date
    Apr 2007
    Posts
    127

    linked list again

    hi all
    Code:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    #define ADD "add"
    #define PRINT "print"
    #define STOP  "STOP"
    
    struct str
    {
            char name[50];
            char age[50];
            struct str *next;
    };
    
    struct str  *get();
    
    int main()
    {
            struct str *current,*root;
            char *command;
    
            if(!(current=malloc(sizeof(struct str))))
            {
                    fprintf(stderr,"Allocating FALID\n");
                    exit(1);
            }
            current->next=current;
            root=current;
    
            printf("Enter Command (add,print):");
            scanf("&#37;s",command);/*fgets is not working why*/
            getchar();
    
         while(current !=0)
         {
            if(strcmp(command,ADD)==0)
            {
                    current = get();
                    printf("Your Command:");
                    scanf("%s",command);
                    getchar();
            }
            else if(strcmp(command,PRINT)==0)
            {
                            current->next=0;/*End The List*/
                            current=root;
                            printf("Name %s",current->name);
                            printf("Age %s\n",current->age);
            }
            else
            {
                    fprintf(stderr,"Undefined Command %s\n",command);
                    printf("Your Command:");
                    scanf("%s",command);
                    getchar();/*fllushing input stream*/
            }
         current=current->next;
         }
         printf("By\n");
         return 0;
    }
    
    struct str  *get()
    {
            struct str *input;
            input=malloc(sizeof(struct str));
            input->next=input;
            printf("Name:\n");
            scanf("%s",input->name);
            printf("Age:\n");
            scanf("%s",input->age);
            return (input);
    }
    input is ok ;
    but
    when it comes to the print command
    i am stuck in there
    here's what i got
    storm@St0rM-MaN:~/Desktop/c# ./linked-o
    Enter Command (add,print):add
    Name:
    Fiky
    Age:
    15
    Your Command:add
    Name:
    Storm
    Age:
    17
    Your Command:add
    Name:
    Nothing
    Age:
    400000
    Your Commandrint
    Name Age
    Name Age
    By
    it's not printing any thing at all
    although i make the current->next=0
    witch ends the input
    and then i make current pointer points to the root pointer witch is the first pointer in the linked list
    and when i used fgets to get command it always give me
    undefined command
    so my questions are
    why fgets is not working
    and
    why it's not printing?

    thanks all
    Last edited by St0rM-MaN; 07-04-2007 at 12:14 PM.

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Your fgets() was probably not working because you didn't remove the newline from the buffer it filled. Or maybe it's because of this:
    Code:
    char *command;
    You cannot read a string into a dangling pointer like that. You have to dynamically allocate memory for command, or declare it as an array.

    Also, perhaps you want to read command inside the while loop?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    life is a nightmare
    Join Date
    Apr 2007
    Posts
    127
    right
    so what about printing the linked list ?
    thanks

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Not part of your problem, but you might want to use stricmp instead of strcmp.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    It's actually the way you're creating the list.
    Code:
            if(strcmp(command,ADD)==0)
            {
                    current = get();
    You can't just assign current to get(). That won't change root->next or whatever.

    The trouble is that you already have an element in the list, then you go to add a new, dynamically allocated element. What to do?

    The easiest solution is probably to set root to NULL at first, in case no elements are added to the list. It would complicate the logic somewhat -- when you go to add an element to the list, you have to check if root is NULL -- but you wouldn't waste any memory.

    Also, setting input->next to NULL in get() makes more sense than setting it to input and then setting it to NULL in the if(print) conditional. And, at the beginning, current->next would be set to NULL, following this same logic.

    [edit]
    Not part of your problem, but you might want to use stricmp instead of strcmp.
    Then again, you might not. strcmp() is ANSI standard, whereas stricmp() is a POSIX function (and a Borland extension). It's not as portable. If you want a case-insensitive string comparision function, it's best to write your own with tolower() -- unless you want only POSIX compatibility. [/edit]
    Last edited by dwks; 07-04-2007 at 01:22 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    life is a nightmare
    Join Date
    Apr 2007
    Posts
    127
    dwks
    i will try what you said
    thanks

  7. #7
    life is a nightmare
    Join Date
    Apr 2007
    Posts
    127
    You can't just assign current to get(). That won't change root->next or whatever.

    The trouble is that you already have an element in the list, then you go to add a new, dynamically allocated element. What to do?

    The easiest solution is probably to set root to NULL at first, in case no elements are added to the list. It would complicate the logic somewhat -- when you go to add an element to the list, you have to check if root is NULL -- but you wouldn't waste any memory.

    Also, setting input->next to NULL in get() makes more sense than setting it to input and then setting it to NULL in the if(print) conditional. And, at the beginning, current->next would be set to NULL, following this same logic.
    The easiest solution is probably to set root to NULL at first
    but when i do this i will loss the linked list

    Also, setting input->next to NULL in get() makes more sense than setting it to input and then setting it to NULL
    i can't get that
    if i set input->next to null
    each time i call malloc to allocate space for input that will give me a new link right
    then i end this link by set ->next to null
    am i right ?

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    What I mean is this.
    Code:
    ITEM *root = NULL;
    ITEM *current = root;
    
    if(add_element) {
        if(!root) {
            root = allocate_element();
            root = read_element();
            current = root;
        }
        else {
            current->next = allocate_element();
            current->next = read_element();
            current = current->next;
        }
    }
    That is, current always points to the previous element in the list, so that you can use current->next to allocate the next element; except when root is NULL, which means that the list is empty.

    Alternatively, you could do this.
    Code:
    ITEM *root = NULL;
    ITEM **current = &root;
    
    if(add_element) {
        *current = allocate_element();
        *current = read_element();
        *current = &((*current)->next);
    }
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    life is a nightmare
    Join Date
    Apr 2007
    Posts
    127
    Code:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    struct info
    {
            char name[50];
            char age[50];
    
            struct info *next;
    };
    
    struct info * allocate(void);
    void get_elements(struct info *t);
    
    #define ADD    "add"
    #define PRINT  "print"
    
    int main()
    {
                    struct info *root;
                    struct info *current;
                    char *command;
                    int x=0;
    
                    root=NULL;
    
                    while(1)
                    {
                            printf("Enter Command:");
                            scanf("&#37;s",command);
                            getchar();
                            if(strcmp(command,ADD)==0)
                            {
                                    if(root==NULL)
                                    {
                                            root=allocate();
                                            get_elements(root);
                                            current=root;
                                    }
                                    else
                                    {
    
                                            current->next=allocate();
                                            get_elements(current->next);
                                            current=current->next;
                                    }
                            }
                            else if(strcmp(command,PRINT)==0)
                            {
                                    if(root==NULL)
                                    {
                                            fprintf(stderr,"There Is No List\n");
                                            exit(1);
                                    }
                                    else
                                            {
                                                    current=root;
                                                    printf("---------------------------------------\n");
                                                    printf("Recorde\t\tName\t\tAge\n");
                                                    printf("--------------------------------------\n");
                                                    while(current!=NULL)
                                                    {
                                                            x++;
                                                            printf("%d\t\t%s\t\t%s\n",x,current->name,current->age);
                                                            current=current->next;
    
                                                    }
                                                    break;
                                    }
                    }
                            else
                            {
                            printf("Undefined Command %s\n",command);
                            }
            }
            exit(EXIT_SUCCESS);
    }
    struct info *allocate()
    {
            struct info *t;
                    t=malloc(sizeof(struct info));
                    return t;
    }
    
    void get_elements(struct info *t)
    {
            printf("Enter Your Name:");
            scanf("%s",t->name);
            getchar();
            printf("Enter Your Age:");
            scanf("%s",t->age);
            getchar();
    
    }
    offffffffffffffffff finally it works
    thanks all

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by dwks View Post
    Then again, you might not. strcmp() is ANSI standard, whereas stricmp() is a POSIX function (and a Borland extension). It's not as portable. If you want a case-insensitive string comparision function, it's best to write your own with tolower() -- unless you want only POSIX compatibility.
    Perhaps, but for someone who is obviously just beginning to learn to program, I suspect portability is the least of his worries.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #11
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Code:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    #define ADD    "add"
    #define PRINT  "print"
    
    struct info
    {
        char name[50];
        char age[50];
        struct info *next;
    };
    
    struct info * allocate(void);
    void get_elements(struct info *t);
    
    int main()
    {
        struct info *root;
        struct info *current;
        char *command;
        int x=0;
    
        root=NULL;
    
        while(1)
        {
            printf("Enter Command:");
            scanf("&#37;s",command);   // You should use fgets, u can avoid using getchar after scanf
            getchar();
            
            if( strcmp(command,ADD)==0 )
            {
                if(root==NULL)
                {
                     root=allocate();
                     get_elements(root);
                     current=root;
                }
                else
                {
                     current->next=allocate();
                     get_elements(current->next);
                     current=current->next;
                }
            }
            else if(strcmp(command,PRINT)==0)
            {
                if(root==NULL)
                {
                     fprintf(stderr,"There Is No List\n");
                     exit(1);
                }
                else
                {
                     current=root;
                     printf("---------------------------------------\n");
                     printf("Recorde\t\tName\t\tAge\n");
                     printf("--------------------------------------\n");
                     while(current!=NULL)
                     {
                          x++;
                          printf("%d\t\t%s\t\t%s\n",x,current->name,current->age);
                          current=current->next;
                     }
                     break;
                }
             }
             else
                  printf("Undefined Command %s\n",command);
        }
    
        getchar();
        return 0;
    }
    
    struct info * allocate(void)
    {
        return malloc (sizeof struct info);
    }
    
    void get_elements(struct info *t)
    {
            printf("Enter Your Name:");
            scanf("%s",t->name);   // fgets(t->name,sizeof t->name, stdin);
            getchar();  
            printf("Enter Your Age:");
            scanf("%s",t->age);  // fgets(t->age,sizeof t->age, stdin)
            getchar();
    }
    You indendation should be good, to be a good programmer. And look at the comments along the code.

    ssharish2005

  12. #12
    life is a nightmare
    Join Date
    Apr 2007
    Posts
    127
    Perhaps, but for someone who is obviously just beginning to learn to program, I suspect portability is the least of his worries.
    thanks but i am not that level
    You indendation should be good, to be a good programmer. And look at the comments along the code.
    i am trying
    thanks
    thanks dwks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ Linked list program need help !!!
    By dcoll025 in forum C++ Programming
    Replies: 1
    Last Post: 04-20-2009, 10:03 AM
  2. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  3. Reverse function for linked list
    By Brigs76 in forum C++ Programming
    Replies: 1
    Last Post: 10-25-2006, 10:01 AM
  4. Template Class for Linked List
    By pecymanski in forum C++ Programming
    Replies: 2
    Last Post: 12-04-2001, 09:07 PM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM