It is an assignment to create a drink machine simulator.
I have a problem with number 3 sprite its not alined with the rest. And i would like to know how to add special characters to add borders around the menu and create a table.

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cctype>
using namespace std;

struct Machine
{
    string name;
    double cost;
    int num;
};

void init(Machine []);
int menu(Machine[]); 
void payment(double);

int main()
{
    Machine drink[5];
    int choice;
    double made=0;
    init(drink);
    choice=menu(drink);
    while(choice!=5)
    {
        payment(drink[choice].cost);
        made+=drink[choice].cost;
        drink[choice].num--;
        choice=menu(drink);  
    }
    cout<<"Today the machine has made $"<<setprecision(2)<<fixed<<made<<endl;
    system("pause");
    return 0;
}

void payment(double p)
{
    double pay;
    cout<<"Your drink costs $"<<setprecision(2)<<fixed<<p<<endl;
    cout<<"Enter payment: ";
    cin>>pay;
    while(pay<0||pay>1.||pay<p)
    {
        cout<<"please insert the correct amount for your drink!\n";
        cout<<"maximum payment is $1.00\n";
        cout<<"Enter payment: ";
        cin>>pay;
    }
    cout<<"Your change is: $"<<setprecision(2)<<fixed<<pay-p<<endl;
    return;
}

void init(Machine d[])
{
    ifstream infile("DrinkMachineInventory.txt");

    if(infile.fail())
    {
        cout << "Could not find the file DrinkMachineInventory.txt \n";
        cout << "Exiting the program\n";
        exit(0);
    }

    int i=0;
    char ch;
    string word= "";

    while(!infile.eof())
    {
        word= "";
        ch = infile.get();
        while(true)
        {
            if(isdigit(ch) || ch == '\n')
                break;
            else
                word += ch;
            ch = infile.get();
        }

        if(word != "")
        {
            d[i].name = word;
            infile >> d[i].cost >> d[i].num ;
            i++;
        }
    }

    infile.close();   
}

int menu(Machine d[])
{
    int choice=8,i;
    bool soldout=true;
    while((choice<1||choice>6)||soldout)
    {
        soldout=false;
        cout<<"Menu\n";
        cout<<"      Drink      Cost\tleft\n";
        for(i=0;i<5;i++)
        {
            cout<<i+1<<". "<<setw(17)<<left<<d[i].name<<"\t";
            cout<<setprecision(2)<<fixed<<d[i].cost<<"\t"<<d[i].num<<endl;
        }
        cout<<"6. Exit\n";
        cout<<"Enter Choice ";
        cin>>choice;
        if(choice<1||choice>6)
            cout<<"invalid entry\n";
        else
            if(d[choice-1].num==0)
            {cout<<"sold out\n";
        soldout=true;
        }
    }
    return choice-1;
}

DrinkMachineInventory.txt-
Coca-Cola 0.75 20
Root Beer 0.75 20
Sprite 0.75 20
Spring Water 0.80 20
Apple Juice 0.95 20

instead of spaces or tabs use setw

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    cout << setw(10) << "First" << setw(10) << "Last" << endl;
    cout << setw(10) << "Somename" << setw(10) << "lname" << endl;
    cout << setw(10) << "Somename" << setw(10) << "lname" << endl;
}

Now I see that you have used it once, but in other places you have used a tab :/ maybe that isn't the problem but it's probably worth investigating.

This seems to be a poorly designed loop,

while(!infile.eof())
    {
        word= "";
        ch = infile.get();
        while(true)
        {
            if(isdigit(ch) || ch == '\n')
                break;
            else
                word += ch;
            ch = infile.get();
        }

What happens if no digits or newline is found at all? Infinite loop.

Edited 5 Years Ago by pseudorandom21: n/a

I agree with Pseudorandom21 on both of these points, especially the latter: when I tested the code myself (using GCC 4.4.1 running through Code::Blocks 10.5 for Windows), I found that the program would hang and crash until I changed that particular loop to test for end-of-file.

As for the box characters, this chart shows the ones in use in US PC systems. Note that it is completely non-portable and may not work consistently even on PCs.

EDIT: I just tried these codes, and they did not work in the default codepage that Windows pops up when running from Code::Blocks. I'll continue looking for information on this, but I can't promise that you'll ever get consistent results.

Edited 5 Years Ago by Schol-R-LEA: n/a

Thanks, can you show me an example cus ive tried everything to fix the loop but im stuck at a dead end.

Thanks, can you show me an example cus ive tried everything to fix the loop but im stuck at a dead end.

You could perhaps try extracting the two values from the end leaving the remaining text...
Or just fix that loop so it finds the index of the last character, then create a substring for the name of the drink using that index--then parse the two values.

Is this what you mean..

do{
    ifstream InFile;
    InFile.open(INPUT_FILE);
    if(InFile){
          Machine soda[NUM_DRINKS];
          int index = 0;
          while(InFile>>soda[index].name>>soda[index].cost
                      >>soda[index].num)
                      {
                           for(int i=0; i< strlen(soda[index].name);i++)
                           {
                                   if(soda[index].name[i]=='_')
                                   {
                                      soda[index].name[i]='';}
                                      }
           if(++index == NUM_DRINKS)
           {
               break;
           }
           
}
      InFile.close();   
}
char choice;
    double amountInserted = 0.0;
    double changeAmount =  0.0;
    double total = 0.0;
    
    do{
        cout<<"\n\n"<<"Drink Machine Simulator!";
        cout<<"\n"<<"---------------------------"<<endl;
        cout<<"Options\t"<<"Drink Name\t"<<"Cost\t"<<"Number in Machine";
        cout<<"\n"<<"-------\t"<<"----------\t"<<"-----\t"<<"---------------";
    for(int d =0; d < numDrinks; d++)
    {
        cout<<endl<<setw(4)<< char(d+49)<<"\t"<<Soda[d].name
            <<"\t"<<Soda[d].cost<<setw(13)<<Soda[d].num;
    }
    cout<<endl<<endl<<"Enter Drink Option or Press Any key to quit: ";
    cin>>choice;
    
    if(choice>='1'&&choice<='5')
    {
          while(Soda[choice-49].num ==0)
          {
               cout<<endl<<"Sold Out..Try Again!!";
               cout<<endl<<endl<<"Enter other drink option except,"
                   <<Soda[choice-49].name<<":";
               cin>>choice;
          }
    cout<<endl<<"Insert Amount for"<<Soda[choice-49].name<<":";
    cin>>amountInserted;
    
          while(amountInserted < 0||amountInserted >1)
          {
               cout<<endl<<"Invalid amount!"<<endl<<"Insert between $1.00: ";
               cin>> amountInserted;
          }
    changeAmount = amountInserted - Soda[choice-49].cost;
          
          while(changeAmount < 0.0)
          {
               cout<<endl<<"Insufficient Fund!"<<endl
                   <<"You are Short:$"<<setprecision(2)<<fixed<<changeAmount;
               cout<<endl<<"Please Insert: ";
               cin >>amountInserted;
          while(amountInserted < 0.0||amountInserted >1.0)
          {
               cout<<"Insert between $1.00: ";
               cin>>amountInserted;
          }
          changeAmount = changeAmount + amountInserted;
}
    cout<<endl<<"Your change:$"<<setprecision(2)<<fixed<<changeAmount;
    total +=Soda[choice-49].num;
}
}
          while(choice>='1'&& choice<='5');
          cout<<endl<<endl<<"Drink Machine Simulator"
          cout<<endl<<"---------------------------"<<endl;
          cout<<endl<<"Drink Name\t"<<"Cost\t"<<"Number in Machine";
          cout<<endl<<"------------\t"<<"------\t"<<"--------------------";
          for(int d=0;d<numDrinks;d++)
          {
              cout<<endl<<Soda[d].name<<"\t"<<Soda[d].cost<<setw(13)<<Soda[d].num;
          }
          cout<<endl<<"\nTotal Amount of Sales:$ "<<setprecision(2)<<fixed<<total;
}

While it is probably more than I should be giving you, since it is very nearly the complete program, I figured this would make it clearer to you. I am especially pleased to have found out how to print the box drawing characters correctly, as well.

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <cctype>


using namespace std;

// border sections
const char upperLeftCorner = '\xDA';
const char upperRightCorner = '\xBF';
const char lowerLeftCorner = '\xC0';
const char lowerRightCorner = '\xD9';
const char horizontalLine = '\xC4';
const char verticalLine = '\xB3';

struct Machine
{
    string name;
    double cost;
    int num;
};

void init(Machine []);
int menu(Machine[]);
void payment(double);

int main()
{
    Machine drink[5];
    int choice;
    double made=0;
    init(drink);
    choice=menu(drink);
    while(choice!=5)
    {
        payment(drink[choice].cost);
        made+=drink[choice].cost;
        drink[choice].num--;
        choice=menu(drink);
    }
    cout<<"Today the machine has made $"<<setprecision(2)<<fixed<<made<<endl;

    return 0;
}

void payment(double p)
{
    double pay;
    cout<<"Your drink costs $"<<setprecision(2)<<fixed<<p<<endl;
    cout<<"Enter payment: ";
    cin>>pay;
    while(pay<0||pay>1.||pay<p)
    {
        cout<<"please insert the correct amount for your drink!\n";
        cout<<"maximum payment is $1.00\n";
        cout<<"Enter payment: ";
        cin>>pay;
    }
    cout<<"Your change is: $"<<setprecision(2)<<fixed<<pay-p<<endl;
    return;
}

void init(Machine d[])
{
    ifstream infile("DrinkMachineInventory.txt");

    if(infile.fail())
    {
        cout << "Could not find the file DrinkMachineInventory.txt \n";
        cout << "Exiting the program\n";
        exit(0);
    }

    int line = 0;
    char ch;
    string word = "";

    while(!infile.eof() && !infile.fail())
    {
        word = "";
        ch = infile.get();
        while(true)
        {
            if(isdigit(ch) || ch == '\n' || infile.eof())
                break;
            else
                word += ch;
            ch = infile.get();
        }

        if(word != " " && word != "")
        {
            d[line].name = word;
            infile >> d[line].cost >> d[line].num ;
            line++;
        }
    }

    infile.close();
}

int menu(Machine d[])
{
    int choice=8;
    bool soldout=true;
    while((choice < 1) || (choice > 6) || soldout)
    {
        soldout=false;

        cout << upperLeftCorner;
        for (int i = 0; i < 40; i++)
            cout << horizontalLine;
        cout << upperRightCorner << endl;


        cout << setw(5) << left << verticalLine << setw(15) << right << "Menu" << setw(22) << right << verticalLine << endl;
        cout << setw(5) << left << verticalLine
             << setw(9) << right << "Drink" << setw(9) << " "
             << setw(6) <<  "Cost"
             << setw(6) << "Left"
             << setw(7) << right << verticalLine << endl;

        for(int i=0; i<5; i++)
        {
            cout << setw(5) << left << verticalLine
                 << i+1 << ". " << setw(17) << left << d[i].name
                 << setw(6) << setprecision(2) << fixed << d[i].cost
                 << setw(6) << d[i].num
                 << setw(5) << right << verticalLine << endl;
        }
        cout << setw(4) << left << verticalLine
             << setw(6) << right << "6. Exit"
             << setw(31) << right << verticalLine << endl;

        cout << setw(6) << left << verticalLine
             << setw(6) << right << "Enter Choice "
             << setw(23) << right << verticalLine << endl;

        cout << lowerLeftCorner;
        for (int i = 0; i < 40; i++)
            cout << horizontalLine;
        cout << lowerRightCorner << endl;

        cin>>choice;
        if(choice<1||choice>6)
            cout<<"invalid entry\n";
        else if(d[choice-1].num==0)
        {
            cout<<"sold out\n";
            soldout=true;
        }
    }
    return choice-1;
}

Edited 5 Years Ago by Schol-R-LEA: n/a

Perhaps I'm mistaken but I believe there are drinks with spaces in the name, I'm not aware of how your solution will properly deal with that.

After a lot of thought about dealing with strange drink names such as "7 UP" or "Coke 0" or something, the one solution that sticks out in my mind as the best is:

1) Remove the two tokens from the end of each line and cast them to their proper types, after which you will be left with the name of the drink.

Thank you! Schoil-R-LEA

For pseudorandom21-What do you mean by two tokens?

Thank you! Schoil-R-LEA

For pseudorandom21-What do you mean by two tokens?

Any group of non-whitespace characters is a token.

This article has been dead for over six months. Start a new discussion instead.