cstructcs50bubble-sort

Getting "subscripted value is not an array, pointer, or vector" error and I don't know why


// 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.


Solution

  • 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;
                }
            } 
        }
    }