0
// Practice working with structs
// Practice applying sorting algorithms

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUM_CITIES 10

typedef struct
{
    string city;
    int temp;
}
avg_temp;

avg_temp temps[NUM_CITIES];

void sort_cities(void);

int main(void)
{
    temps[0].city = "Austin";
    temps[0].temp = 97;

    temps[1].city = "Boston";
    temps[1].temp = 82;

    temps[2].city = "Chicago";
    temps[2].temp = 85;

    temps[3].city = "Denver";
    temps[3].temp = 90;

    temps[4].city = "Las Vegas";
    temps[4].temp = 105;

    temps[5].city = "Los Angeles";
    temps[5].temp = 82;

    temps[6].city = "Miami";
    temps[6].temp = 97;

    temps[7].city = "New York";
    temps[7].temp = 85;

    temps[8].city = "Phoenix";
    temps[8].temp = 107;

    temps[9].city = "San Francisco";
    temps[9].temp = 66;

    sort_cities();

    printf("\nAverage July Temperatures by City\n\n");

    for (int i = 0; i < NUM_CITIES; i++)
    {
        printf("%s: %i\n", temps[i].city, temps[i].temp);
    }
}

// TODO: Sort cities by temperature in descending order
void sort_cities(void)
{
    // Add your code here
    int swap_counter = 1;
    int origtemp = 0;
    int j = 0;
    int n;
    if (strlen(temps[j+1].city) > strlen(temps[j].city))
        {
            n = strlen(temps[j+1].city);
        }
        else if (strlen(temps[j+1].city) < strlen(temps[j].city))
        {
            n = strlen(temps[j].city);
        }
        else
        {
            n = strlen(temps[j].city);
        }
    do
    {
        while (swap_counter > 0)
        {
            swap_counter--;
        }
        for (int i = 0; i < loops; i++)
        {
            origtemp += temps[i].temp;
            if (temps[i].temp > temps[i + 1].temp)
            {
                swap_counter++;
                while (temps[i].temp > temps[i + 1].temp)
                {
                    temps[i].temp--;
                }
                while (temps[i+1].temp < origtemp)
                {
                    temps[i].temp;
                }
                for (int b = 0; b < n; b++)
                {
                    temps[i][b].city = temps[i+1][b].city;
                    if (temps[i][b].city == '\0')
                    {
                        temps[i][b+1].city = '\0';
                        temps[i][b].city = temps[i+1][b].city;
                    }
                    if (temps[i+1][b].city == '\0')
                    {
                        temps[i][b].city = '\0';
                        break;
                    }
                    i++;
                }
                while (origtemp > 0)
                {
                    origtemp--;
                }
            }
        }
    }
    while (swap_counter != 0);
    return temps[i].city, temps[i].temp;
}

The error happens on the line which is:

temps[i][b].city = temps[i+1][b].city;

What i'm trying to do is swap each character of temps[i][b].city with temps[i+1][b].city with special conditions. If temps[i][b].city == to NULL at any point, NULL is moved forward so the character of temps[i+1][b].city can replace it. If temps[i+1][b].city is equal to NULL, that means that the word is shorter, so temps[i][b].city is just cut off right there and it breaks. The problem is that it's not letting me go into each character of the arrays.

This is actually a cs50 problem, and the point is to try and sort the temperature of different locations by lowest to highest. To do this, I have chosen to use bubble sort. If the temperature of the first location is higher than the second location, the temperatures and the locations are swapped. We run this over and over until the entire thing is sorted. To swap the letters of the locations, I want to just go over each character of the arrays and swap them, while still taking in account NULL. However, when I try this, I get an error.

15
  • @Harr It seems you mean for example temps[i].city[b] = temps[i+1].city[b]; instead of temps[i][b].city = temps[i+1][b].city;. But in any case the presented code does not make sense. Commented Jun 24, 2023 at 19:24
  • 2
    temps is a one-dimensional array. Therefore, it does not make sense to for example write temps[i][b]. That would only make sense with a two-dimensional array (i.e. an array of arrays). As stated by someone else, you probably mean temps[i].city[b] instead. Commented Jun 24, 2023 at 19:49
  • 1
    @AndreasWenzel I think that the question should not be reopened becuase my previous comment in fact is an answer to the question. He should read comments. Commented Jun 24, 2023 at 19:50
  • 3
    @VladfromMoscow If you want to answer the question, post an answer. And answering a question doesn't mean it should be closed. There might be other valid reasons to close the question. Commented Jun 24, 2023 at 19:51
  • 1
    In your struct, because you use string [this is a cs50 typedef for char *], you do not want to swap char-by-char. The .city values are pointers to string literals in read-only memory. Your swap should be the entire struct: avg_temp tmp = temps[i]; temps[i] = temps[i + 1]; temps[i + 1] = tmp; Commented Jun 24, 2023 at 19:56

1 Answer 1

1

You are trying to access a single dimensional array like it's a two dimensional array. That is the error you're seeing.

Your sorting seems overly complex. You have stated you wish to use bubble sort. That's acceptable for such a small sample size.

Assuming we stick with the less than ideal global variable temps, there are only two cases where we need to swaps two cities: if the temp is higher in the first city, or if the temps are the same and the first name is "greater" than the second.

void sort_cities(void) {
    for (int i = 0; i < NUM_CITIES - 1; i++) {
        for (int j = 0; j < NUM_CITIES - i - 1; j++) {
            if (temps[j].temp < temps[j+1].temp) { 
                continue;
            }
            
            if (temps[j].temp > temps[j+1]) {
                avg_temp tmp = temps[j];
                temps[j] = temps[j+1];
                temps[j+1] = tmp;
                continue;
            }

            int name_cmp = strcmp(temps[j].city, temps[j+1].city);

            if (name_cmp == 1) {
                avg_temp tmp = temps[j];
                temps[j] = temps[j+1];
                temps[j+1] = tmp;
            }
        } 
    }
}

This might be simplified to avoid writing two swaps.

void sort_cities(void) {
    for (int i = 0; i < NUM_CITIES - 1; i++) {
        for (int j = 0; j < NUM_CITIES - i - 1; j++) {
            if (temps[j].temp > temps[j+1].temp || 
                (temps[j].temp == temps[j+1].temp && 
                 strcmp(temps[j].city, temps[j+1].city) == 1)) {
                avg_temp tmp = temps[j];
                temps[j] = temps[j+1];
                temps[j+1] = tmp;
            }
        } 
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.