Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    20
    Rep Power
    0

    Problem regarding pointers in C


    Hi Guys,

    I have a silly problem here....

    1. I am trying to create a linked list list (code:1) ..The for loop in it always takes 1 input more than it is supposed to be but displays it correctly .. REASON...:confused:
    2. I want to write some data into the file then print the same.. But the program crashes when it is about to print ... i tried REWIND and storing the initial add in a seperate var and then reassigning it back to the file pointer ..But still the prog crashes...If anybody can figure it out.. would be grt.. :D
    code:1
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    struct stud
    {
    
    int data;
    struct stud *next;
    
    };
    typedef struct stud node;
    
    int main()
    {
    node *head,*p;
    int i,n;
    
    head = (node*)malloc(sizeof(node));
    p = head;
    printf("Enter the no. of u want to create");
    scanf("%d",&n);
    
    for(i=0;i<n;i++)
    {
      p->next =  (node*)malloc(sizeof(node));
      scanf("%d ",&p->data);
      //p->data = i;
      p = p->next;
    }
    p->next = NULL;
    
    p = head;
    printf("\n\n");
    
    while(p->next != NULL)
    {
       printf("%d  ",p->data);
       p = p->next;
    }
    return 0;
    }
    code:2
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    int main()
    {
    
     FILE *fp,*tp;
     char ch;
     fp=fopen("kill.txt","w+");
     tp = fp;
     fprintf(fp,"45\n12\n589\n568\n\n");
    
     //fp = tp;
     rewind(fp);
     while(fscanf(fp,"%c",&ch) != EOF)
            printf("%c",ch);
    
     fclose(fp);
     return 0;
    
    }
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    159
    Rep Power
    19
    For the second program, how do you expect to write to a read only file?

    How do you know that the file opened correctly in the first place? You never checked!

    Jim
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Code:
     FILE *fp,*tp;
     char ch;
     fp=fopen("kill.txt","r");
     tp = fp;
     fprintf(fp,"45\n12\n589\n568\n\n");
    
     fp = tp;
    Whiskey-Tango-Foxtrot, Oscar? (WTF, over?) Why? What do you think that you are trying to do there?

    And could you please clean up your indenting?
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Originally Posted by kurosaki
    Hi Guys,

    I have a silly problem here....

    1. I am trying to create a linked list list (code:1) ..The for loop in it always takes 1 input more than it is supposed to be but displays it correctly .. REASON...:confused:
    Because that's what you're telling the program to do.

    Code:
    int main()
    {
        node *head,*p;
        int i,n;
    
        // You start out here having created an extra node
        head = (node*)malloc(sizeof(node));
        p = head;
        printf("Enter the no. of u want to create");
        scanf("%d",&n);
    
        // Since you created an extra node to start with,
        //    you will end up having created n+1 nodes; eg, if you 
        //    enter 5 for the number of nodes that you want to create,
        //    then you will end up having created six nodes.
        //  Though I don't see how you would be prompting for n+1
        //      input values as you describe.  I only see it prompting
        //      for n values, each of which is stored in the 
        //      previously created node, with the last node 
        //      never receiving a value to store.
        //  Normal procedure is to initialize head to NULL (empty list) 
        //      and to then iterate through the for-loop creating
        //      a new node and inserting that into the list along
        //      with reading in its input value and setting its next
        //      field to NULL (assuming that you're appending it
        //      onto the end of the list as you are doing here).
        //      Of course, you would need to test for head being 
        //      NULL in order to handle that special case, but you
        //      would end up with n nodes and not n+1.
        for(i=0;i<n;i++)
        {
            p->next =  (node*)malloc(sizeof(node));
            scanf("%d ",&p->data);
            //p->data = i;
            p = p->next;
        }
        p->next = NULL;
    
        p = head;
        printf("\n\n");
    
        // Here, you skip the last node.
        // Walk through that loop with pencil and paper and see
        //      for yourself what's happening.  In fact, walking 
        //      through your code playing computer with pencil and 
        //      paper on a small example is a very valuable
        //     debugging tool when working with data structures
        //      such as linked lists.
        //  You stay in that loop so long as there's another node
        //      following the current one.  That is exactly what you
        //      are testing for there.  When you get to the last node,
        //      it does not have another node following it, so you
        //      drop out of the loop and do not print the contents
        //      of that last node.
        while(p->next != NULL)
        {
            printf("%d  ",p->data);
            p = p->next;
        }
    
        // Why are you returning 1 here instead of 0?
        // Are you that convinced that your program will never run
        //     successfully?
        return 1;
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    20
    Rep Power
    0
    @ dwise1 aol.

    Sorry.. :o .. I posted the code that i was working on without editing it...

    As for fp = tp;

    since rewind() didn't work..I tried reassigning the initial address of the file to "fp" again by storing it in "tp"..I want to write data into the file then display the same..
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    20
    Rep Power
    0
    @ jimblumberg

    I used "ERROR.h" .. The file opens correctly and writes data onto it but won't read from it..
  12. #7
  13. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Originally Posted by kurosaki
    1. I am trying to create a linked list list (code:1) ..The for loop in it always takes 1 input more than it is supposed to be but displays it correctly .. REASON...:confused:
    On the question of why it "asks" for one more input than it should, the problem is due to the space you added in the scanf: "%d ".

    I modified your for loop slightly by adding an actual prompt:
    Code:
        for(i=0;i<n;i++)
        {
            p->next =  (node*)malloc(sizeof(node));
            printf("Enter value #%d: ", i+1);
            scanf("%d ",&p->data);
            //p->data = i;
            p = p->next;
        }
    This is the output I got:
    C:TEST>a
    Enter the no. of u want to create4
    Enter value #1: 1
    2
    Enter value #2: 3
    Enter value #3: 4
    Enter value #4: 5


    1 2 3 4
    C:TEST>
    Then I removed that space:
    Code:
        for(i=0;i<n;i++)
        {
            p->next =  (node*)malloc(sizeof(node));
            printf("Enter value #%d: ", i+1);
            scanf("%d",&p->data);
            //p->data = i;
            p = p->next;
        }
    This is the output I got:
    C:TEST>a
    Enter the no. of u want to create4
    Enter value #1: 1
    Enter value #2: 2
    Enter value #3: 3
    Enter value #4: 4


    1 2 3 4
    C:TEST>
    Now, if you had yourself added an actual prompt for the entry of each data value, then you would have seen that odd behavior for yourself. Quick-and-dirty rarely works to your advantage.

    PS

    For what you were probably trying to do, it would have worked better to have placed that space in front of the %d rather than after it.

    I tried this:
    Code:
    scanf(" %d ",&p->data);
    which places the space before the %d and it worked just fine:
    C:TEST>a
    Enter the no. of u want to create4
    Enter value #1: 1
    Enter value #2: 2
    Enter value #3: 3
    Enter value #4: 4


    1 2 3 4
    C:TEST>
    Since my professional use of C has always been in embedded systems (no console), I have very limited practical experience with the subtleties of interpretation of scanf format strings. I would guess that placing the space after leaves scanf expecting more, whereas placing it before will satisfy scanf even if there is not preceding white space (much more important with the %c flag).

    Comments on this post

    • kurosaki agrees : Solved it..
    Last edited by dwise1_aol; October 16th, 2013 at 11:18 AM.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    20
    Rep Power
    0

    Thumbs up


    Originally Posted by dwise1_aol
    Because that's what you're telling the program to do.

    Code:
    int main()
    {
        node *head,*p;
        int i,n;
    
        // You start out here having created an extra node
        head = (node*)malloc(sizeof(node));
        p = head;
        printf("Enter the no. of u want to create");
        scanf("%d",&n);
    
        // Since you created an extra node to start with,
        //    you will end up having created n+1 nodes; eg, if you 
        //    enter 5 for the number of nodes that you want to create,
        //    then you will end up having created six nodes.
        //  Though I don't see how you would be prompting for n+1
        //      input values as you describe.  I only see it prompting
        //      for n values, each of which is stored in the 
        //      previously created node, with the last node 
        //      never receiving a value to store.
        //  Normal procedure is to initialize head to NULL (empty list) 
        //      and to then iterate through the for-loop creating
        //      a new node and inserting that into the list along
        //      with reading in its input value and setting its next
        //      field to NULL (assuming that you're appending it
        //      onto the end of the list as you are doing here).
        //      Of course, you would need to test for head being 
        //      NULL in order to handle that special case, but you
        //      would end up with n nodes and not n+1.
        for(i=0;i<n;i++)
        {
            p->next =  (node*)malloc(sizeof(node));
            scanf("%d ",&p->data);
            //p->data = i;
            p = p->next;
        }
        p->next = NULL;
    
        p = head;
        printf("\n\n");
    
        // Here, you skip the last node.
        // Walk through that loop with pencil and paper and see
        //      for yourself what's happening.  In fact, walking 
        //      through your code playing computer with pencil and 
        //      paper on a small example is a very valuable
        //     debugging tool when working with data structures
        //      such as linked lists.
        //  You stay in that loop so long as there's another node
        //      following the current one.  That is exactly what you
        //      are testing for there.  When you get to the last node,
        //      it does not have another node following it, so you
        //      drop out of the loop and do not print the contents
        //      of that last node.
        while(p->next != NULL)
        {
            printf("%d  ",p->data);
            p = p->next;
        }
    
        // Why are you returning 1 here instead of 0?
        // Are you that convinced that your program will never run
        //     successfully?
        return 1;

    :D :D No sir, That "return 1;" was a mistake .. I edited it some time ago.. Ur explanation's great ... I missed out on the "head" node.. There shouldn't be a head->data, just the "head->next",pointer to the next field..... :chomp: I will trace it on the paper once..

    Thank u much.. :winkgrins

    What abt the 2nd one...?
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    20
    Rep Power
    0
    Originally Posted by dwise1_aol
    On the question of why it "asks" for one more input than it should, the problem is due to the space you added in the scanf: "%d ".

    I modified your for loop slightly by adding an actual prompt:
    Code:
        for(i=0;i<n;i++)
        {
            p->next =  (node*)malloc(sizeof(node));
            printf("Enter value #%d: ", i+1);
            scanf("%d ",&p->data);
            //p->data = i;
            p = p->next;
        }
    This is the output I got:

    Then I removed that space:
    Code:
        for(i=0;i<n;i++)
        {
            p->next =  (node*)malloc(sizeof(node));
            printf("Enter value #%d: ", i+1);
            scanf("%d",&p->data);
            //p->data = i;
            p = p->next;
        }
    This is the output I got:

    Now, if you had yourself added an actual prompt for the entry of each data value, then you would have seen that odd behavior for yourself. Quick-and-dirty rarely works to your advantage.

    PS

    For what you were probably trying to do, it would have worked better to have placed that space in front of the %d rather than after it.

    I tried this:
    Code:
    scanf(" %d ",&p->data);
    which places the space before the %d and it worked just fine:

    Since my professional use of C has always been in embedded systems (no console), I have very limited practical experience with the subtleties of interpretation of scanf format strings. I would guess that placing the space after leaves scanf expecting more, whereas placing it before will satisfy scanf even if there is not preceding white space (much more important with the %c flag).
    Actually this solved my problem.... :D I had never experienced this with "scanf" before... Thank u much again...
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Originally Posted by kurosaki
    :D :D No sir, That "return 1;" was a mistake .. I edited it some time ago.. Ur explanation's great ... I missed out on the "head" node.. There shouldn't be a head->data, just the "head->next",pointer to the next field..... :chomp: I will trace it on the paper once..

    Thank u much.. :winkgrins

    What abt the 2nd one...?
    head is just a pointer to the first node, so then oh yes indeed there should be a head->data, that just being the data field of the first node in the list. Though you would not use head to set that value, but rather you would use the normal code within the for loop, though that code needs to be modified slightly.

    Please pardon the hand-waving here, but I think you will be able to follow what I'm describing. Your idea is basically good, using p to point you to the end of the list which is where you want to append each new node. Some approaches maintain a tail pointer for that purpose, especially with doubly-linked lists.

    My approach would be to initialize head and p to NULL; that means that the list is empty. All node creation and initialization would be within the for-loop. In the loop, test whether p is NULL. If p is NULL, which means that this will be the first node to be added to the list, then malloc and assign the address to p and also to head. If p is not NULL, then malloc the new node and assign the address to p->next, after which you then assign p->next to p. Either branch through that if-else will create the new node, set pointers to point to it properly, and set p to point to the new node. Now all you need to do is to set the data and pointer fields of the new node and you're done with that node and with that iteration of the loop.

    With pencil and paper, try sketching through the process to see how the steps work, which will also show you how to code it.
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    20
    Rep Power
    0
    Originally Posted by dwise1_aol
    Because that's what you're telling the program to do.

    Code:
    int main()
    {
        node *head,*p;
        int i,n;
    
        // You start out here having created an extra node
        head = (node*)malloc(sizeof(node));
        p = head;
        printf("Enter the no. of u want to create");
        scanf("%d",&n);
    
        // Since you created an extra node to start with,
        //    you will end up having created n+1 nodes; eg, if you 
        //    enter 5 for the number of nodes that you want to create,
        //    then you will end up having created six nodes.
        //  Though I don't see how you would be prompting for n+1
        //      input values as you describe.  I only see it prompting
        //      for n values, each of which is stored in the 
        //      previously created node, with the last node 
        //      never receiving a value to store.
        //  Normal procedure is to initialize head to NULL (empty list) 
        //      and to then iterate through the for-loop creating
        //      a new node and inserting that into the list along
        //      with reading in its input value and setting its next
        //      field to NULL (assuming that you're appending it
        //      onto the end of the list as you are doing here).
        //      Of course, you would need to test for head being 
        //      NULL in order to handle that special case, but you
        //      would end up with n nodes and not n+1.
        for(i=0;i<n;i++)
        {
            p->next =  (node*)malloc(sizeof(node));
            scanf("%d ",&p->data);
            //p->data = i;
            p = p->next;
        }
        p->next = NULL;
    
        p = head;
        printf("\n\n");
    
        // Here, you skip the last node.
        // Walk through that loop with pencil and paper and see
        //      for yourself what's happening.  In fact, walking 
        //      through your code playing computer with pencil and 
        //      paper on a small example is a very valuable
        //     debugging tool when working with data structures
        //      such as linked lists.
        //  You stay in that loop so long as there's another node
        //      following the current one.  That is exactly what you
        //      are testing for there.  When you get to the last node,
        //      it does not have another node following it, so you
        //      drop out of the loop and do not print the contents
        //      of that last node.
        while(p->next != NULL)
        {
            printf("%d  ",p->data);
            p = p->next;
        }
    
        // Why are you returning 1 here instead of 0?
        // Are you that convinced that your program will never run
        //     successfully?
        return 1;
    I solved this by interchanging the position of "p = p->next;" statement(in for and while loop) with the scanf and printf statements in the respective loops.... :D
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    20
    Rep Power
    0
    Originally Posted by dwise1_aol
    head is just a pointer to the first node, so then oh yes indeed there should be a head->data, that just being the data field of the first node in the list. Though you would not use head to set that value, but rather you would use the normal code within the for loop, though that code needs to be modified slightly.

    Please pardon the hand-waving here, but I think you will be able to follow what I'm describing. Your idea is basically good, using p to point you to the end of the list which is where you want to append each new node. Some approaches maintain a tail pointer for that purpose, especially with doubly-linked lists.

    My approach would be to initialize head and p to NULL; that means that the list is empty. All node creation and initialization would be within the for-loop. In the loop, test whether p is NULL. If p is NULL, which means that this will be the first node to be added to the list, then malloc and assign the address to p and also to head. If p is not NULL, then malloc the new node and assign the address to p->next, after which you then assign p->next to p. Either branch through that if-else will create the new node, set pointers to point to it properly, and set p to point to the new node. Now all you need to do is to set the data and pointer fields of the new node and you're done with that node and with that iteration of the loop.

    With pencil and paper, try sketching through the process to see how the steps work, which will also show you how to code it.
    Hahah.. grt man.. :)

    I got it.. I just understood in minutes what i couldn't in a couple of hours..

    here's what i tried..

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    struct stud
    {
    
    int data;
    struct stud *next;
    
    };
    typedef struct stud node;
    
    int main()
    {
    node *head,*p;
    int i,n;
    
    p = head = NULL;
    printf("Enter the no. of u want to create");
    scanf("%d",&n);
    for(i=0;i<=n;i++)
    {
    if(p == NULL)
    {
      p = head = (node *)malloc(sizeof(node));   
    }
    else
    {
      p->next =  (node*)malloc(sizeof(node));
      p = p->next;
      scanf("%d",&p->data);
    //p->data = i;       
     }
    p->next = NULL;
    p = head;
    
    printf("\n\n");
    
    while(p->next != NULL)
    {
       p = p->next;          
       printf("%d  ",p->data);
    }
    return 0;
    }
  24. #13
  25. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Close, but it won't compile because you left out a close brace. You should have seen that if you had indented your code properly.

    Also, the report loop needs to be corrected.
    Code:
          // WRONG!  You told it to loop n+1 times.
     // for(i=0;i<=n;i++)
        for(i=0;i<n;i++)
        {
            if(p == NULL)
            {
                p = head = (node *)malloc(sizeof(node));   
            }
            else
            {
                p->next =  (node*)malloc(sizeof(node));
                p = p->next;
            }  // you left out this close brace  
    
            scanf("%d",&p->data);
            p->next = NULL;  // this needed to be moved into the loop
        }
        p = head;
    
        printf("\n\n");
    
        // this needed to be changed.  The old code skipped the last node
    //    while(p->next != NULL)
        while(p != NULL)
        {
        // needed to reverse the order on these guys 
           printf("%d  ",p->data);
           p = p->next;          
        }
        return 0;
    Last edited by dwise1_aol; October 16th, 2013 at 12:12 PM.
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    20
    Rep Power
    0
    Originally Posted by dwise1_aol
    Close, but it won't compile because you left out a close brace. You should have seen that if you had indented your code properly.

    Also, the report loop needs to be corrected.
    Code:
          // WRONG!  You told it to loop n+1 times.
     // for(i=0;i<=n;i++)
        for(i=0;i<n;i++)
        {
            if(p == NULL)
            {
                p = head = (node *)malloc(sizeof(node));   
            }
            else
            {
                p->next =  (node*)malloc(sizeof(node));
                p = p->next;
            }  // you left out this close brace  
    
            scanf("%d",&p->data);
            p->next = NULL;  // this needed to be moved into the loop
        }
        p = head;
    
        printf("\n\n");
    
        // this needed to be changed.  The old code skipped the last node
    //    while(p->next != NULL)
        while(p != NULL)
        {
        // needed to reverse the order on these guys 
           printf("%d  ",p->data);
           p = p->next;          
        }
        return 0;
    ****.. ! That's a lot of mistakes... :(

    Got a bit confused at the "move the p->next = NULL into the for loop" part.. but now everything is clear...All thnx to u.

    What about the File i/o problem...?
  28. #15
  29. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Have you read the responses you got already? For my part, I cannot understand what purpose that FILE*, tp, is supposed to have. I learned and started using C professionally circa 1990, C++ shortly thereafter. In all those 23 years, I have never seen anyone try anything like that. I'm not even completely certain what would happen.

    jimblumberg pointed out quite correctly that you never checked whether that file had failed to open. I never just blindly assume that fopen succeeded, but rather I always check and I always handle failure to open a file. Do you know what fopen will return if it fails to open the file? If you don't, then RTFM! ("Read The Manual!"); if you don't have the documentation in a book or on your computer, then Google on man page fopen and choose from the 101,000 hits (though not every single one of those hits is for C). The Return Value section will tell you what value is returned in case of failure. You need to test fp for being that value and only use it if it is not that value.

    You need to fix and eliminate that problem before we can say any more.


    BTW, works for me -- MinGW gcc on WinXP:
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    int main()
    {
    
        FILE *fp;
        char ch;
        fp=fopen("kill.txt","w+");
        if (fp == NULL)
            printf("file failed to open\n");
        else
        {
            fprintf(fp,"45\n12\n589\n568\n\n");
    
            rewind(fp);
            while(fscanf(fp,"%c",&ch) != EOF)
                   printf("%c",ch);
    
            fclose(fp);
        }
        return 0;
    }
    Code:
    C:TEST>a
    45
    12
    589
    568
    
    
    C:TEST>dir k*.txt
     Volume in drive C has no label.
     Volume Serial Number is XXXX-XXXX
    
     Directory of C:\otros\pc14402\dcw\PROJECTS\TEST
    
    10/16/2013  12:08                20 kill.txt
                   1 File(s)             20 bytes
                   0 Dir(s)   9,818,234,880 bytes free
    
    C:TEST>xxd kill.txt
    0000000: 3435 0d0a 3132 0d0a 3538 390d 0a35 3638  45..12..589..568
    0000010: 0d0a 0d0a                                ....
    
    C:TEST>

    PS

    If your program does fail to open the file, then you will need to know why. errno is a global variable that contains the error code of the last error. When fopen fails, it sets the value of errno.

    Read the man page for errno; eg, at http://linux.die.net/man/3/errno. Be sure to read both the Description at top and the Notes at the bottom. Also at the bottom is a link to the perror() function, which will print out a description of the error.
    Last edited by dwise1_aol; October 16th, 2013 at 02:35 PM.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo