Sorting members of a structure using pointer function

I am trying to perform the bulk of the work intended by calling the swap function. The point of the program is to initialize the week array in the main function, then use the swap function to sort the structure member 'temp' of the array, from least to greatest. The end result should sort the array values for temp from least to greatest (and keep the day names with the corresponding temp).

Ive already tried a variety of syntax (incorrectly) and am not sure what I am doing wrong. I am trying to learn the proper way to access structure members as pointers and manipulate them with external functions.

struct weather {
    char day[10];
    float temp;
};

void swap (struct weather *p);



int main()
{
    struct weather week[7] = {
    { "Sunday", 72.5 },
    { "Monday", 68.4 },
    { "Tuesday", 75.0 },
    { "Wednesday", 73.8 },
    { "Thursday", 65.1 },
    { "Friday", 72.8 },
    {"Saturday", 75.2 }
};

swap(week);

int x;
puts("This week's forecast from coldest to warmest:");
for(x=0;x<7;x++)
    printf("%10s %.1f degrees\n",
            week[x].day,
            week[x].temp);

return(0);
}


void swap (struct weather *p){

int x;
int t;
for (x=0;x<7;x++){
    if (p[x+1].temp < p[x].temp){
        t = p[x+1].temp;
        p[x+1].temp = p[x].temp;
        p[x].temp = t;
        }
    }
}

I would expect the second member array (temp) of the structure to be in ascending order. It is not, and Saturday is listed with a temp of 0. The intent of my question is to ensure I am manipulating the values of the array in memory properly.

Upvotes: 0

Views: 946

Answers (2)

David C. Rankin
David C. Rankin

Reputation: 84559

Well, you are going about this somewhat backwards. swap is one operation where you simply swap two elements of an array, and sort is a separate operation where you iterate over the elements in an array testing where each element should be placed to end up in sorted order using swap to change the location of the elements within the array.

Your array is your array of struct (e.g. week). So when you sort the array, you will want to swap elements. To swap elements of type struct weather *, you need nothing more than:

void swap (struct weather *a, struct weather *b)
{
    struct weather tmp = *a;
    *a = *b;
    *b = tmp;
}

The sort operation is a separate operation (which you should write a simple compare function and sort calling qsort). But, for educational purposes and for small arrays you can choose any sort algorithm you want, such as a simple insertion sort to sort your array week by the temp member (in ascending order), e.g.

void sorttemp (struct weather *p, int nmemb)
{
    for (int i = 0; i < nmemb; i++)
        for (int j = i; j > 0 && p[j].temp < p[j-1].temp; j--)
            swap (&p[j], &p[j-1]);
}

(note: above, swap is called by providing the address of (e.g. pointer to) each element, swap (&p[j], &p[j-1]);)

Putting it altogether, you can do:

#include <stdio.h>

struct weather {
    char day[10];
    float temp;
};

void swap (struct weather *a, struct weather *b)
{
    struct weather tmp = *a;
    *a = *b;
    *b = tmp;
}

void sorttemp (struct weather *p, int nmemb)
{
    for (int i = 0; i < nmemb; i++)
        for (int j = i; j > 0 && p[j].temp < p[j-1].temp; j--)
            swap (&p[j], &p[j-1]);
}

int main (void)
{
    struct weather week[7]  =  {{ "Sunday", 72.5 },
                                { "Monday", 68.4 },
                                { "Tuesday", 75.0 },
                                { "Wednesday", 73.8 },
                                { "Thursday", 65.1 },
                                { "Friday", 72.8 },
                                { "Saturday", 75.2 }};

    sorttemp (week, 7);

    puts ("This week's forecast from coldest to warmest:");
    for (int x = 0; x < 7; x++)
        printf ("%10s %.1f degrees\n", week[x].day, week[x].temp);

}

Example Use/Output

$ ./bin/sort_week_temp
This week's forecast from coldest to warmest:
  Thursday 65.1 degrees
    Monday 68.4 degrees
    Sunday 72.5 degrees
    Friday 72.8 degrees
 Wednesday 73.8 degrees
   Tuesday 75.0 degrees
  Saturday 75.2 degrees

Look things over an let me know if you have further questions.

Upvotes: 1

Rishabh Gupta
Rishabh Gupta

Reputation: 824

you would need two for loops, one inside the other to strictly order the temp in ascending order.

I couldn't understand if you wanted only temp to be sorted or the relevant day to be sorted as well, so I have given both functions to do it.

mind you that the swap function pollutes the data in the original array, so the day and the temperature do not correspond to the initial original array.

if you want to sort the weather struct, first you need to create an array of pointers to the weather struct, then you have to fill that array with addresses from the actual array and then sort this array of pointers according to temp

here is the code:

#include<stdio.h>

struct weather {
    char day[10];
    float temp;
};

void swap (struct weather *p);
void sort (struct weather *p[]);

int main()
{
    int x;

    struct weather week[7] = {
        { "Sunday", 72.5 },
        { "Monday", 68.4 },
        { "Tuesday", 75.0 },
        { "Wednesday", 73.8 },
        { "Thursday", 65.1 },
        { "Friday", 72.8 },
        { "Saturday", 75.2 }
    };

    struct weather *sorted[7];
    for (x = 0; x < 7; x++) {
        sorted[x] = &week[x];
    }

    sort(sorted);

    puts("This week's forecast from coldest to warmest:");
    for(x=0;x<7;x++)
        printf("%10s %.1f degrees\n",
                (*sorted[x]).day,
                (*sorted[x]).temp);

    swap(week);

    puts("This week's forecast from coldest to warmest:");
    for(x=0;x<7;x++)
        printf("%10s %.1f degrees\n",
                week[x].day,
                week[x].temp);

    return(0);
}


void swap (struct weather *p) {
    int x, i;
    int t;
    for (x=0;x<6;x++){
        for (i = x; i < 7; i++){
            if (p[i].temp < p[x].temp){
                t = p[i].temp;
                p[i].temp = p[x].temp;
                p[x].temp = t;
            }
        }
    }
}

void sort (struct weather *p[]) {
    int x, i;
    struct weather *t;
    for (x=0;x<6;x++){
        for (i = x; i < 7; i++){
            if ((*p[i]).temp < (*p[x]).temp){
                t = p[i];
                p[i] = p[x];
                p[x] = t;
            }
        }
    }
}

output:

This week's forecast from coldest to warmest:
  Thursday 65.1 degrees
    Monday 68.4 degrees
    Sunday 72.5 degrees
    Friday 72.8 degrees
 Wednesday 73.8 degrees
   Tuesday 75.0 degrees
  Saturday 75.2 degrees
This week's forecast from coldest to warmest:
    Sunday 65.0 degrees
    Monday 68.0 degrees
   Tuesday 72.0 degrees
 Wednesday 72.0 degrees
  Thursday 73.0 degrees
    Friday 75.0 degrees
  Saturday 75.2 degrees

Upvotes: 0

Related Questions