Thread: Sorting a struct array(numerical+alphabetical)

  1. #1
    Registered User
    Join Date
    Jan 2018
    Posts
    18

    Sorting a struct array(numerical+alphabetical)

    (C programming)I have been trying for the past hours to sort a struct array with 10 elements. However I did not understand much at the sites where I looked for more information. Can anyone solve this, or at least give me a start.

    Here is an example from the textfile im using:

    82476,Watermelon Dorado Double India Pale Ale,31.90,355.00,Ale brittisk-amerikansk stil,Imperial/Dubbel IPA,Flaska,USA,Ballast Point Brewing,10.00

    And here is my code:

    Code:
    void listanr(void)
        
        {
    
    
            char *oneline, *tok;
            char envara[512];
            char delim[] = ",";
            FILE *fp;
            int i;
    
    
    
    
            struct vara
            {
                int nummer;
                char namn[100];
                float pris;
                float volym;
                char typ[100];
                char stil[100];
                char forpackning[20];
                char land[20];
                char producent[50];
                float alkoholhalt;
    
    
            } items[100];
    
    
    
    
            if ((fp = fopen("varor.csv", "r")) == NULL)
            {
                fprintf(stderr, "Filen varor.csv gick inte att öppna\n");
                exit(-1);
            }
    
    
            for (i = 0; i < 100 && fgets(envara, 512, fp); i++)
            {
                envara[strlen(envara) - 1] = '\0';
                oneline = strdup(envara);
    
    
                tok = strtok(oneline, delim);
                items[i].nummer = atoi(tok);
                tok = strtok(NULL, delim);
                strncpy(items[i].namn, tok, (max(strlen(tok), sizeof(items[0].namn))));
                tok = strtok(NULL, delim);
                items[i].pris = atof(tok);
                tok = strtok(NULL, delim);
                items[i].volym = atof(tok);
                tok = strtok(NULL, delim);
                strncpy(items[i].typ, tok, strlen(tok));
                tok = strtok(NULL, delim);
                strncpy(items[i].stil, tok, strlen(tok));
                tok = strtok(NULL, delim);
                strncpy(items[i].forpackning, tok, strlen(tok));
                tok = strtok(NULL, delim);
                strncpy(items[i].land, tok, min(strlen(tok), sizeof(items->land)));
                tok = strtok(NULL, delim);
                strncpy(items[i].producent, tok, strlen(tok));
                tok = strtok(NULL, delim);
                items[i].alkoholhalt = atof(tok);
    
    
                printf("nummer: %d\n"
                    "namn: %s\n"
                    "pris: %f\n"
                    "volym: %f\n"
                    "typ: %s\n"
                    "stil: %s\n"
                    "forpackning: %s\n"
                    "land: %s\n"
                    "producent: %s\n"
                    "alkoholhalt: %f\n\n",
                    items[i].nummer,
                    items[i].namn,
                    items[i].pris,
                    items[i].volym,
                    items[i].typ,
                    items[i].stil,
                    items[i].forpackning,
                    items[i].land,
                    items[i].producent,
                    items[i].alkoholhalt
    );
    
    
          
    
    
                free(oneline);
            }
    
    
            fclose(fp);
        }
    Last edited by emano12; 01-23-2018 at 01:17 PM. Reason: typo

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    How would you sort an int array with 10 elements?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Also posted here and here.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Some points to ponder.

    1. atoi/atof return 0 on error, which isn't exactly useful. Use strtod etc, where you can check for errno to determine success.

    2. It's a waste of time calling strdup(), when you can just as easily strtok the original buffer.

    3. None of your strncpy calls is correct.
    Where you do bother to call min(), you don't allow space for the \0 if the initial string doesn't fit. Strncpy() will not append a \0 for you if there isn't a \0 in the copied part of the input string.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2017
    Posts
    157
    To sort your array you can use qsort:
    C library function - qsort()

    What are actually the criteria to sort ?

  6. #6
    Registered User
    Join Date
    Jan 2018
    Posts
    18
    I´m supposed to store the data in 1. numerical order(based on "nummer")
    and 2. alphabetical order(based on "namn")

    the program I have for the moment is working just fine, just having a hardtime getting started with the sorting.

  7. #7
    Registered User
    Join Date
    Jun 2017
    Posts
    157
    Here is a little demo to sort structs:
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct
    {
      char name[25];
      int age;
    }TPerson;
    
    TPerson People[] = 
    {
      {"Lisa", 33},
      {"Anna", 22},
      {"Debbie", 44}
    };
    
    #define NUM_PEOPLE sizeof(People) / sizeof(People[0])
    
    int age_sorter(const void* p1, const void* p2)
    {
      TPerson *person1 = p1;
      TPerson *person2 = p2;
    
      return person1->age - person2->age;
    }
    
    int name_sorter(const void* p1, const void* p2)
    {
      TPerson *person1 = p1;
      TPerson *person2 = p2;
    
      return strcmp(person1->name, person2->name);
    }
    
    int main()
    {
      int i;
    
      printf("People sorted by name:");
      qsort(People, NUM_PEOPLE, sizeof(TPerson), name_sorter);
      for (i = 0; i <NUM_PEOPLE; i++)
        printf("\n%s\t%d", People[i].name, People[i].age);
    
      printf("\n\nPeople sorted by age:");
      qsort(People, NUM_PEOPLE, sizeof(TPerson), age_sorter);
      for (i = 0; i <NUM_PEOPLE; i++)
        printf("\n%s\t%d", People[i].name, People[i].age);
    }

  8. #8
    Registered User
    Join Date
    Jan 2018
    Posts
    18
    thank you Oldguy2! really helped

  9. #9
    Registered User
    Join Date
    Jan 2018
    Posts
    18

    almost there, i hope

    This is a sample from my code. I have applied some of your example code to my program. However i have been trying to understand what to input where I wrote "XXXX" in my sorting alghoritm. Any ideas? Am i doing something or right or is it all wrong. The only error that occurs is "XXXX" is undeclared, but i can not figure out the right input.

    Code:
    #define NUM_ITEMS sizeof(items) / sizeof(items[0])
    
    struct vara
            {
                int nummer;
                char namn[100];
                float pris;
                float volym;
                char typ[100];
                char stil[100];
                char forpackning[20];
                char land[20];
                char producent[50];
                float alkoholhalt;
    
    
            } items[100];
    
    for (i = 0; i < 100 && fgets(envara, 512, fp); i++)
            {
                envara[strlen(envara) - 1] = '\0';
                oneline = strdup(envara);
    
    
                tok = strtok(oneline, delim);
                items[i].nummer = atoi(tok);
                tok = strtok(NULL, delim);
                strncpy(items[i].namn, tok, (max(strlen(tok), sizeof(items[0].namn))));
                tok = strtok(NULL, delim);
                items[i].pris = atof(tok);
                tok = strtok(NULL, delim);
                items[i].volym = atof(tok);
                tok = strtok(NULL, delim);
                strncpy(items[i].typ, tok, strlen(tok));
                tok = strtok(NULL, delim);
                strncpy(items[i].stil, tok, strlen(tok));
                tok = strtok(NULL, delim);
                strncpy(items[i].forpackning, tok, strlen(tok));
                tok = strtok(NULL, delim);
                strncpy(items[i].land, tok, min(strlen(tok), sizeof(items->land)));
                tok = strtok(NULL, delim);
                strncpy(items[i].producent, tok, strlen(tok));
                tok = strtok(NULL, delim);
                items[i].alkoholhalt = atof(tok);
    
    
                int nummer_sortering(const void* n1, const void* n2)
                {
                    items *XXXX = n1;
                    items *XXXX = n2;
    
    
                    return items->nummer - items->nummer;
                }
    
    
                printf("\n\nItems sorted by number:");
                qsort(items, NUM_ITEMS, sizeof(items), nummer_sortering);
                for (i = 0; i < NUM_ITEMS; i++)
                    printf("nummer: %d\n"
                        "namn: %s\n"
                        "pris: %f\n"
                        "volym: %f\n"
                        "typ: %s\n"
                        "stil: %s\n"
                        "forpackning: %s\n"
                        "land: %s\n"
                        "producent: %s\n"
                        "alkoholhalt: %f\n\n",
                        items[i].nummer,
                        items[i].namn,
                        items[i].pris,
                        items[i].volym,
                        items[i].typ,
                        items[i].stil,
                        items[i].forpackning,
                        items[i].land,
                        items[i].producent,
                        items[i].alkoholhalt);

  10. #10
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Code:
    items *XXXX;
    For XXXX to be declared as an variable you need to use an typename in front of it. "items" is an arrayname.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  11. #11
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    I strongly warn you that using the "qsort" function without your instructor permission will likely get your project marked with a failing grade.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  12. #12
    Registered User
    Join Date
    Jan 2018
    Posts
    18

    crash

    It is ok to use qsort! I have changed my code to this instead, it shows no error but crashes when im trying to run it.

    Code:
    int nummer_sortering(const void* n1, const void* n2)
    			{
    
    
    				const struct vara *item1 = n1;
    				const struct vara *item2 = n2;
    
    
    				return item1->nummer - item2->nummer;
    			}
    
    printf("\n\nVaror sorterade på varunummer:");
    			qsort(items, NUM_ITEMS, sizeof(items), nummer_sortering);
    			for (i = 0; i < NUM_ITEMS; i++)
    			{
    
    
    				printf("nummer: %d\n"
    					"namn: %s\n"
    					"pris: %f\n"
    					"volym: %f\n"
    					"typ: %s\n"
    					"stil: %s\n"
    					"forpackning: %s\n"
    					"land: %s\n"
    					"producent: %s\n"
    					"alkoholhalt: %f\n\n",
    					items[i].nummer,
    					items[i].namn,
    					items[i].pris,
    					items[i].volym,
    					items[i].typ,
    					items[i].stil,
    					items[i].forpackning,
    					items[i].land,
    					items[i].producent,
    					items[i].alkoholhalt);
    			}

  13. #13
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    qsort(3): sort array - Linux man page

    The qsort() function sorts an array with nmemb elements of size size. The base argument points to the start of the array.
    Code:
    qsort(items, NUM_ITEMS, sizeof(items), nummer_sortering);
    NUM_ITEMS is likely wrong.

    sizeof(items) is wrong.

    Tim S
    Last edited by stahta01; 01-27-2018 at 05:18 PM.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  14. #14
    Registered User
    Join Date
    Jan 2018
    Posts
    18
    Thank you for the response. How could I solve it? Tried with "vara" but didnt work.

  15. #15
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by emano12 View Post
    Thank you for the response. How could I solve it? Tried with "vara" but didnt work.
    You fix it by reading about qsort and then fixing your code.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sorting array of struct inside struct
    By blueboyz in forum C Programming
    Replies: 13
    Last Post: 04-24-2012, 02:15 AM
  2. Alphabetical sorting in a character array?
    By YPavluk in forum C Programming
    Replies: 10
    Last Post: 10-28-2011, 08:35 AM
  3. C++ Alphabetical sorting, etc Help
    By Lucifix in forum C Programming
    Replies: 5
    Last Post: 05-17-2010, 01:29 AM
  4. Alphabetical sorting function
    By typer in forum C Programming
    Replies: 6
    Last Post: 05-20-2006, 02:35 AM
  5. Sorting in alphabetical order
    By fkheng in forum C Programming
    Replies: 3
    Last Post: 08-24-2003, 09:07 AM

Tags for this Thread