Search code examples
ccs50

How do I add another array to a set, specifically a string?


This is a bit of a follow-up to the last post I made on here, now asking how to add another string array to my previous text-based item shop. Someone was very helpful last time, telling me I could keep track of prices and item names via arrays, which while I still don't fully understand, am trying to make use of. I should also preface that my code is extremely simple, since I'm just barely starting with programming.

My code is the following,

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

int string_to_price(string item)
{
    //The array/s that's catching me up.
    string items[] = { "Matchbox", "Wool Hat", "Heavy Coat", "Canned Food" };
    int prices[] = { 50, 125, 250, 25 };
    string description[] = { "They're cheap, and they'll keep you warm.\n", "A nice, handknit, cozy hat. Thank my ma for that!\n", "This coat'll keep you cozy through the night no matter the situation!\n", "It don't taste too good, but it'll last you a lifetime. Eat up!" };

    for (size_t i = 0; i < (sizeof items / sizeof *items); i++)
    {
        if (0 == strcmp(items[i], item))
        {
            return prices [i];
        }
    }
    //Item not available
    return -1;
}

int main(void)
{
    //Dialogue, then ask for item selection
    int buckaroonies = 500;
    printf("Hey chum, welcome to the item shop. You've got a handful 'o coin on ya, huh?\nYou came to the right place, we got the best wares in town!\n\n");
    printf("Store:\n\nMatchbox - 50\nWool Hat - 125\nHeavy Coat - 250\nCanned Food - 25\n");
    string select = get_string ("What'll it be? You have %i buckaroonies, pal.\n", buckaroonies);

    //Get item price from selection
    int price = string_to_price(select);

    //Return dialogue based on selected item.
    if (-1 == price)
    {
        printf("We aint got that, pal.\n");
    }
    else
    {
        char c = get_char ("That %s'll cost ya %i buckaroonies. %s You want it?\n", select, price, description);
    }
}

I'm surely doing something wrong, because I'm getting an error telling me "description" isn't a declared string.


Solution

  • Your arrays (items, prices, description) are local to the string_to_price function - meaning they can only be accessed inside that function. main can't see them. There are a couple of fixes.

    Also, the function should probably return the index, not the price so you can access the other arrays.

    Make the arrays global:

    #include <cs50.h>
    #include <stdio.h>
    #include <string.h>
    
    string items[] = { "Matchbox", "Wool Hat", "Heavy Coat", "Canned Food" };
    int prices[] = { 50, 125, 250, 25 };
    string description[] = { "They're cheap, and they'll keep you warm.\n", "A nice, handknit, cozy hat. Thank my ma for that!\n", "This coat'll keep you cozy through the night no matter the situation!\n", "It don't taste too good, but it'll last you a lifetime. Eat up!" };
    const size_t num_items = sizeof(items) / sizeof(items[0]);
    
    int find_item(string item)
    {
        for (size_t i = 0; i < num_items ; i++)
        {
            if (0 == strcmp(items[i], item))
            {
                return i;
            }
        }
        //Item not available
        return -1;
    }
    
    int main(void)
    {
        //Dialogue, then ask for item selection
        int buckaroonies = 500;
        printf("Hey chum, welcome to the item shop. You've got a handful 'o coin on ya, huh?\nYou came to the right place, we got the best wares in town!\n\n");
        printf("Store:\n\nMatchbox - 50\nWool Hat - 125\nHeavy Coat - 250\nCanned Food - 25\n");
        string select = get_string ("What'll it be? You have %i buckaroonies, pal.\n", buckaroonies);
    
        //Find item from selection
        int index = find_item(select);
    
        //Return dialogue based on selected item.
        if (-1 == item)
        {
            printf("We aint got that, pal.\n");
        }
        else
        {
            char c = get_char ("That %s'll cost ya %i buckaroonies. %s You want it?\n", items[index], prices[index], description[index]);
        }
    }
    

    Since global values are frowned on, another option is to make them local to main and pass as a parameter:

    int find_item(string item, string items[], size_t num_items)
    {
        for (size_t i = 0; i < num_items; i++)
        {
            if (0 == strcmp(items[i], item))
            {
                return i;
            }
        }
        //Item not available
        return -1;
    }
    
    int main(void)
    {
        string items[] = { "Matchbox", "Wool Hat", "Heavy Coat", "Canned Food" };
        int prices[] = { 50, 125, 250, 25 };
        string description[] = { "They're cheap, and they'll keep you warm.\n", "A nice, handknit, cozy hat. Thank my ma for that!\n", "This coat'll keep you cozy through the night no matter the situation!\n", "It don't taste too good, but it'll last you a lifetime. Eat up!" };
        const size_t num_items = sizeof(items) / sizeof(items[0]);
    
        //Dialogue, then ask for item selection
        int buckaroonies = 500;
        printf("Hey chum, welcome to the item shop. You've got a handful 'o coin on ya, huh?\nYou came to the right place, we got the best wares in town!\n\n");
        printf("Store:\n\nMatchbox - 50\nWool Hat - 125\nHeavy Coat - 250\nCanned Food - 25\n");
        string select = get_string ("What'll it be? You have %i buckaroonies, pal.\n", buckaroonies);
    
        //Find item from selection
        int index = find_item(select, items, num_items);
    
        //Return dialogue based on selected item.
        if (-1 == index)
        {
            printf("We aint got that, pal.\n");
        }
        else
        {
            char c = get_char ("That %s'll cost ya %i buckaroonies. %s You want it?\n", items[index], prices[index], description[index]);
        }
    }
    

    Eventually, you will learn structs, which will allow you to keep the data together.

    struct item {
        string name;
        int price;
        string description;
    };
    
    int find_item(string item_name, struct item items[], size_t num_items)
    {
        for (size_t i = 0; i < num_items ; i++)
        {
            if (0 == strcmp(items[i].name, item_name))
            {
                return i;
            }
        }
        //Item not available
        return -1;
    }
    
    int main(void)
    {
       struct item items[] = {
            {"Matchbox", 50, "They're cheap, and they'll keep you warm."},
            {"Wool Hat", 125, "A nice, handknit, cozy hat. Thank my ma for that!"},
            {"Heavy Coat", 250, "This coat'll keep you cozy through the night no matter the situation!"},
            {"Canned Food", 25, "It don't taste too good, but it'll last you a lifetime. Eat up!"}
        };
        const size_t num_items = sizeof(items) / sizeof(items[0]);
    
        //Dialogue, then ask for item selection
        int buckaroonies = 500;
        puts("Hey chum, welcome to the item shop. You've got a handful 'o coin on ya, huh?\nYou came to the right place, we got the best wares in town!\n");
        puts("Store:\n");
        for (size_t i = 0; i < num_items; i++) {
            printf("%s - %d\n", items[i].name, items[i].price);
        }
        string select = get_string ("What'll it be? You have %i buckaroonies, pal.\n", buckaroonies);
    
        //Find item from selection
        int index = find_item(select, items, num_items);
    
        //Return dialogue based on selected item.
        if (-1 == index)
        {
            puts("We aint got that, pal.");
        }
        else
        {
            char c = get_char("That %s'll cost ya %i buckaroonies. %s You want it?\n", items[index].name, items[index].price, items[index].description);
        }
    }