-1

I am trying to use stroi in my "vending machine" code below. I had a working vending machine before I tried to add a feature that allows users to enter characters ("c" for checkout, "a" for add, and "r" for remove) as well. Since my user input can be both int and char I realized I had to convert strings to numbers. I have checked references but none give an example of how to use it with vectors. Can someone please help?

Currently, there is an error located at the int myint1 = stoi(item); line in the if statement in the main. It says "use of undeclared identifier 'i'."

Note: I am fixing my code so it does not run. But when it did, the code breaks after 2 user inputs and I am not sure why.

Here is an example of what I am trying to code:

Vending machine:

----Items----

(5 listed below)

what item would you like to buy? Enter "c" to checkout, "a" for add item and "r" for remove item.

-If user input is an integer, then run the enterSelection function

-If user input is a character (c, a, or r) , then:

if "c" , then run checkout function

if "a", What Item would you like to add and for what price? Then append to menuItems and cost accordingly.

if "r", what item would you like to remove (enter a number)? Then erase the item from menuItems.

Then print: "User input" has been added/removed from the menu.

When the menu is displayed again, the user edit will show.

And yes, I know there are many more problems with my code that I do not know how to fix.

Full Code:

#include <iostream>
#include <vector>
#include <string>
#include <iomanip>

using namespace std;

int item;
float total;


std::vector<string> menuItems = {"Popcorn", "Coconut Clusters" , "Granola Bar" , "Trail Mix" , "Chocolate"};

std::vector<float> cost = {2, 3, 2.50, 1.50, 1};



void vendingMachine() {

  for (int i = 0; i < 5; i++)

    cout << i + 1 << ". " << menuItems[i] << ": $" << cost[i] << endl;

}

void enterSelection() {
  total = 0;

  cout << "Enter your selection: " << flush;
        
    cin >> item;
       
    item = item - 1;
        
    cout << menuItems[item] << ": $" << cost[item] << " has been added to cart." << endl;
    total = total + cost[item];

}

void checkout() {
  cout << "                         " << endl;
  cout << "Proceding to checkout..." << endl;
  cout << "========================" << endl;

  cout << "Amount due: $" << total << endl;


  cout << "Insert money here: $" << flush;
  float money;
  cin >> money;

  while (money < total) {
    float amountOwed = total - money;
    cout << "Please insert another $" << amountOwed << endl;

    cout << "Enter amount: $" << flush;
    float payment;
    cin >> payment;
    money += payment;
    }
    if (money > total) {
      float change = money - total;
      cout << "Thank you! You have $" << change << " change." << endl;
    }

    if (money == total) {
      cout << "Thank you! Have a nice day!." << endl;
    }
}

void add() {
  cout << "What item would you like to add: " << flush;
  string add;
  cin >> add;
  menuItems.push_back(add);
  cout << "For what price: $" << flush;
  int price;
  cin >> price;
  cost.push_back(price);
  cout << add << " for $" << price << "has been added to the menu." << endl; 
}

void remove() {
    cout << "What item would you like to remove (enter a number): " << flush;
    int remove;
    cin >> remove;
    menuItems.erase (menuItems.begin()+remove);
    cout << remove << " has been removed from the menu." << endl;
}


int main() {

  cout.precision(2);
  cout << std::fixed;

  cout << "Vending Machine" << endl;
  cout << "----Items------" << endl;

  vendingMachine();
  cout << "Enter c to checkout" << endl;
  cout << "Enter a to add items" << endl;
  cout << "Enter r to remove items" << endl;
    

  enterSelection();


if (item != 'c' && item != 'a' && item != 'r') {
  int myint1 = stoi(item);
  enterSelection();
} else if (item == 'c') {
    checkout();
} else if (item == 'a') {
    add();
} else if (item == 'r') {
    remove();
}
else {
  cout << "Please enter a number or press c to checkout, a to add item, or r to remove item: " << flush;
}

    
    return 0;
}

The major problem segment of code:

if (item != 'c' || item != 'a' || item != 'r') {
  int myint1 = stoi(item);
  enterSelection();
} else if (item == 'c') {
    checkout();
} else if (item == 'a') {
    add();
} else if (item == 'r') {
    remove();
}
else {
  cout << "Please enter a number or press c to checkout, a to add item, or r to remove item: " << flush;
}
anastaciu
  • 23,467
  • 7
  • 28
  • 53
yeliah
  • 41
  • 6
  • 1
    I think you posted way too much code for a minimal example. std::vector::erase takes an iterator not a value. [http://www.cplusplus.com/reference/vector/vector/erase/](http://www.cplusplus.com/reference/vector/vector/erase/) – drescherjm Aug 13 '20 at 20:46
  • only the `menuItems.erase(remove);` line in the `remove` function has an error but the code does not run the way I intended to even without it – yeliah Aug 13 '20 at 20:46
  • 1
    `if (info != "c" || info != "a" || info != "r")` This is always true, every string is either not equal to "c" or not equal to "a". What you meant to write is `if (info != "c" && info != "a" && info != "r")` – john Aug 13 '20 at 20:47
  • The argument to `menuItems.erase()` has to be an iterator. `remove` is an `int`. – Barmar Aug 13 '20 at 20:47
  • 1
    To answer your headline question: yes. Your issue is likely one of scope. – sweenish Aug 13 '20 at 20:47
  • 2
    I strongly suggest getting out of the habit of using non-const global variables. This is a major source of bugs. – cigien Aug 13 '20 at 20:47
  • `item` is an integer. `info` is `item` converted to a string. How do you expect it to be a letter like `c`? – Barmar Aug 13 '20 at 20:50
  • 2
    You're doing things backwards. If you want to let the user enter either a number or a letter, you have to read the input into a string. If it's not one of the letters, you can then convert the string to a number. – Barmar Aug 13 '20 at 20:52
  • does that mean I shouldn't use sstream? – yeliah Aug 13 '20 at 20:52
  • No, there's no need for that. Just read the line from `cin`. If it's not one of your special characters, convert it to an int with `stoi()` – Barmar Aug 13 '20 at 20:55
  • Your title also doesn't seem to match what you're trying to do. You never use the stringstream in an `if` statement. You use the string `info` in the `if` statement. – Barmar Aug 13 '20 at 20:57
  • oh, i see. I am not sure how to name my problem tho... – yeliah Aug 13 '20 at 20:58
  • Your input could be an integer or a string. The only way to handle this situation is to read the input as a string, and then convert it (if necessary) to an integer. You cannot read it as a integer first and then convert it to a string because any attempt to read a string into an integer will fail. So you need to rewrite this code, make `item` a string not an integer, and then convert it to an integer if that is necessary. You can use a `stringstream` to do the conversion if you want, that is reasonable. – john Aug 13 '20 at 20:59
  • I know I have to use `stoi()` for my problem which is why I used `sstream` in my code. I am unsure how to use `stoi()` when I have vectors – yeliah Aug 13 '20 at 21:03
  • `if (item != 'c' || item != 'a' || item != 'r')` should use `&&` not `||`. See https://stackoverflow.com/questions/26337003/execute-block-if-a-variable-is-not-one-of-some-specific-values – Barmar Aug 13 '20 at 21:45
  • What do vectors have to do with `stoi`? If you want to add the integer to a vector, it doesn't matter how you created the integer. – Barmar Aug 13 '20 at 21:46
  • I think you need to step back and think about what you're doing one step at a time. You seem to be very confused about how things fit together. – Barmar Aug 13 '20 at 21:46
  • And maybe you need to work on a simpler project, as you need to practice the basics. – Barmar Aug 13 '20 at 21:47
  • is this project considered complex? – yeliah Aug 13 '20 at 21:47

1 Answers1

1

To answer your question, you can.

However you are not doing correctly, regardless, you wouldn't need all those conversions, you could compare item directly with a char or int deppending on the type of input you ask for.

We can also continue with std::stoi to convert the input to its int value, you must, however, guard for the aphabetic inputs, these will not be converted, of course, and error derived from this failed conversions should be prevented.

Semi-corrected code with comments:

Running sample

string input; //string input
int item = 0;
float total;
void enterSelection()
{
    total = 0;
    int flag = 0; //flag for input errors

    cout << "Enter your selection: ";

    cin >> input; //input as string

    try
    {
        item = stoi(input); //convert to int
    }
    catch (exception &e) //if string cannot be converted
    {
        //std::cout << e.what(); 
        flag = -1; //if not set flag
    }

    if (flag != -1 && item < 5 && item > 0) //only execute if no exeception cached
    {
        item--;
        cout << menuItems[item] << ": $" << cost[item] << " has been added to cart." << endl;
        total = total + cost[item];
        flag = 0; //reset flag
    }
}
void checkout()
{
    cout << "                         " << endl;
    cout << "Proceding to checkout..." << endl;
    cout << "========================" << endl;

    cout << "Amount due: $" << total << endl;

    cout << "Insert money here: $" << flush;
    float money;

    cin >> money;

    while (money < total)
    {
        float amountOwed = total - money;
        cout << "Please insert another $" << amountOwed << endl;

        cout << "Enter amount: $" << flush;
        float payment;
        cin >> payment;
        money += payment;
    }
    if (money > total)
    {
        float change = money - total;
        cout << "Thank you! You have $" << change << " change." << endl;
    }

    if (money == total)
    {
        cout << "Thank you! Have a nice day!." << endl;
    }
    exit(EXIT_SUCCESS); //exit after checkout
}
int main()
{

    cout.precision(2);
    cout << std::fixed;

    cout << "Vending Machine" << endl;
    cout << "----Items------" << endl;

    vendingMachine();
    cout << "Enter c to checkout" << endl;
    cout << "Enter a to add items" << endl;
    cout << "Enter r to remove items" << endl;

    enterSelection();

    
    while(1) // infinite cycle will exit in checkout
    if (!input.compare("c")) //string has a compare method similar to C strcmp
    {
        checkout();
    }
    else if (!input.compare("a"))
    {
        add();
    }
    else if (!input.compare("r"))
    {
        remove();
    }
    else
    {
        cout << "Please enter a number or press c to checkout, a to add item, or r to remove item: ";
        enterSelection(); //execute enter selection again
    }
    return 0;
}

You still have problems, like input validation and some arithmetic problems in your functions, I just corrected the issues related to what you asked, you should try to solve the other problems by yourself, it's the best way to learn.

Build your code bit by bit, understand what it does and test it, then move on, if you have to ask questions, make them focused, this debugging effort is not usual here, the problems must be specific, posting your whole code for us to check your bugs is usually not well accepted, as you can see for the lack of votes in your question and in my answer.

anastaciu
  • 23,467
  • 7
  • 28
  • 53