Thread: Help with malloc and pointers.

  1. #16
    Registered User
    Join Date
    Nov 2013
    Posts
    16
    Will it not store in in_name?

  2. #17
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Yes it will. I don't even know how I missed that there, but I did, so apologies. Yes that should be fine.

  3. #18
    Registered User
    Join Date
    Nov 2013
    Posts
    16
    Ok, thank you so much. So the big main problem is still occurring. I've figured out my function "filesize" is returning -1.

    Code:
    int filesize(char * filename){
       struct stat status;
       if (stat(filename, &status) == -1)
       {
          return -1;
       }
       else
       {
          return (int) status.st_size;
        }
    }
    Unfortunately, this is the piece of code I was given. I am nowhere near understanding what's going on except that "stat(filename, &status)" apparently is equal to -1. I don't even know what stat does. I'm stuck.

  4. #19
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    That's why they gave us a manual. As it says, -1 is returned on error, and errno is set appropriately. You can use perror to show the system error message:
    Code:
    int filesize(char * filename){
     struct stat status;
     if (stat(filename, &status) == -1)
       {
     perror("stat");
     return -1;
       }
     else
       {
     return (int) status.st_size;
        }
    }
    although I'd be willing to be a dollar to a doughnut that you've passed in a filename that doesn't exist.

  5. #20
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by RElainaJ View Post
    So, does this work?
    Code:
    char in_name[255];
    
    ...
    if (scanf("%s", in_name) != 1)
    For this you have to assume that no input will ever be 255 or more characters. If it happens you're still toast. To be safe you should use a function which limits the size of the input read. fgets for example.

  6. #21
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Read the man page. From your terminal, you can type "man 3 stat", or search for that on the web. That 3 ensures you use section 3 of the man pages, which are for C library functions. You may occassionally want to check section 2 as well, which is system calls.

    So, the code you were given calls the stat function. If stat returns -1 (error), then your function returns -1. Otherwise, your function returns the size as reported by stat.

  7. #22
    Registered User
    Join Date
    Nov 2013
    Posts
    16
    Well, the filesize function was being passed "argv[1]" because that's what the professor told me to do but I changed it to in_name (the name of the file) and it began to work. I really hope changing that won't cause me trouble later on.

  8. #23
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by RElainaJ View Post
    Well, the filesize function was being passed "argv[1]" because that's what the professor told me to do but I changed it to in_name (the name of the file) and it began to work. I really hope changing that won't cause me trouble later on.
    Someone (anduril) mentioned that earlier: are the specs to pass the filename in on the command line (in which case argv[1] is the way to go) or to type it in in response to a prompt, in which case your scanf is the way to go? You'll have to check the specs and follow them.

  9. #24
    Registered User
    Join Date
    Nov 2013
    Posts
    16
    The filename is prompted for in the command line.

    I've gotten much further, actually starting the sorting process before running into another problem. Here's what I have at the moment.
    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int filesize(char * filename)
    {
       struct stat status;
       if (stat(filename, &status) == -1)
       {
          return -1;
       }
       else
       {
         return (int) status.st_size;
       }
    }
    
    
    int compare(const void *elem1, const void *elem2)
    {
        char **e1 = (char **) elem1;
        char **e2 = (char **) elem2;
        if (strcmp(*e1,*e2)<0)
            return -1;
        else if (strcmp(*e1,*e2)>0)
            return 1;
        else
            return 0;
    }
    
    
    void sort(char array[], int size)
    {
        qsort(array, size, sizeof(array[0]), &compare);
    }
    
    
    int main(int argc, char * argv[])
    {
    
        FILE *read;
        char in_name[255];
        int n = 0;
        int j = 0;
        int linecount = 1;
    
       printf("What file should be read?\n");
        if (scanf("%s", in_name) != 1)
        {
          printf("Invalid input.\n");
          return 1;
       }
    
        read = fopen(in_name,"r");
    
        if (read == NULL)
        {
          printf("Cannot open input file.\n");
          return 1;
        }
    
    
        char * data = malloc(filesize(in_name));
    
        data[n] = fgetc(read);
        while (data[n] != EOF)
       {
          if (data[n] == '\n')
          {
             data[n] = '\0';
             linecount++;
          }
          data[++n] = fgetc(read);
       }
         if (data[n] != '\0')
          data[++n] = '\0';
    
        char ** lines = malloc(sizeof(lines[0]) * linecount);
    
        int i = 0;
        while (j < linecount)
        {
          lines[j] = &data[i];
          while(data[i] != '\0')
             i++;
          i++;
          j++;
        }
    
        sort(*lines,linecount);
    
        for (int k = 0; k < linecount; k++)
        {
          printf("%s\n", lines[k]);
        }
    
        fclose(read);
        free(data);
        free(lines);
        return 0;
    }
    The problem is "if (strcmp(*e1,*e2)<0)" and, it seems I'm going about accessing the arrays to sort the wrong way.

  10. #25
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    Why not use a growing array to store the input? Your program would be more portable since you won't need to use stat.

    In regard to your compare function, try reading the example provided in 'man qsort'.
    i dont believe in competition in da field of cboard posts, u see, i believe in a collection of posts each 2 be admired for der own personal statement. when in doubt, ask Willy!

  11. #26
    Registered User
    Join Date
    Nov 2013
    Posts
    16
    Barney- Honestly, I don't know how to use a growing array. I imagine figuring out how to do so, messing up, figuring out what went wrong, and fixing it would tack on more time. I've got a lot of work besides this to do before tomorrow. So... I suppose it's trying to take the easy way out, even if the program won't be as solid. Yes, I'm ashamed of this, but... well... not enough to give up on sleeping at all.

    man sort gives me the parameters but not an example. I wasn't bright enough to pick up on discrepancies there.

  12. #27
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    man sort gives me the parameters but not an example.
    Try another source: qsort(3) - Linux manual page
    i dont believe in competition in da field of cboard posts, u see, i believe in a collection of posts each 2 be admired for der own personal statement. when in doubt, ask Willy!

  13. #28
    Registered User
    Join Date
    Nov 2013
    Posts
    16
    Thank you for the link! Going through it... I think I'm doing something wrong regarding whether I'm using pointers to things or the things themselves? Am I on the right track?

  14. #29
    Registered User
    Join Date
    Nov 2013
    Posts
    16
    I changed
    Code:
    int compare(const void *elem1, const void *elem2)
    {
        char **e1 = (char **) elem1;
        char **e2 = (char **) elem2;
        if (strcmp(*e1,*e2)<0)
            return -1;
        else if (strcmp(e1,e2)>0)
            return 1;
        else
            return 0;
    }

    to
    Code:
    int compare(const void *elem1, const void *elem2)
    {
        char *e1 = (char *) elem1;
        char *e2 = (char *) elem2;
        if (strcmp(e1,e2)<0)
            return -1;
        else if (strcmp(e1,e2)>0)
            return 1;
        else
            return 0;
    }


    Now I'm getting output. However, that output is wrong.
    My input file says
    "goat
    4
    nine
    1
    2
    pink"
    and I'd like to get
    "1
    2
    4
    goat

    nine
    pink"
    Right now, I'm getting
    "t
    nine
    1
    2
    pink\377"
    So I'm losing "goa" in goat and "4" and gaining "\377". These seem like separate problems. Am I pointing to the wrong thing?
    Last edited by RElainaJ; 11-20-2013 at 12:00 AM. Reason: Format

  15. #30
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    qsort requires each element to be of the same length so, obviously, you can't move strings around in an array using it, since they may have different sizes. What you need to do is store a pointer to each string in an array, then sort those pointers, which is what the example in 'man 3 qsort' demonstrates.

    EDIT: As in, the following array would be bad input for qsort:

    char s[] = "the\0cow\0jumped\0over\0the\0moon\0";

    Whereas the following would be good input:

    char *p[] = { s + 0, s + 4, s + 8, s + 15, s + 20, s + 24 };

    This is because the element type of the first array is a 'char' (though you'd need to scale it with a varying size, which doesn't work well with qsort), whereas the element type of the second array is 'char *', and you would be scaling it by exactly 'sizeof (char *)'.
    Last edited by Barney McGrew; 11-20-2013 at 12:06 AM.
    i dont believe in competition in da field of cboard posts, u see, i believe in a collection of posts each 2 be admired for der own personal statement. when in doubt, ask Willy!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 05-19-2010, 02:12 AM
  2. Malloc and pointers
    By taurus in forum C Programming
    Replies: 8
    Last Post: 10-25-2008, 09:00 AM
  3. Problem with malloc and pointers to pointers
    By mike_g in forum C Programming
    Replies: 7
    Last Post: 03-29-2008, 06:03 PM
  4. malloc and pointers
    By St0rM-MaN in forum C Programming
    Replies: 14
    Last Post: 06-20-2007, 11:03 AM
  5. Pointers and malloc
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 03-21-2002, 09:20 PM

Tags for this Thread