sazzy
sazzy

Reputation: 3

reading and printing inputs and C-string in C++

I have a simple program to read and echoed the user's input and calculate the total amount. I'm having trouble with arrays. I want to know how to use an array to read and print each product name and the cost and the find grand total upon checkout. Should I also use functions?

#include <iostream>
#include <cstring>
#include <iomanip>

using namespace std;

const int MAX_CHAR = 100;

void pause();

int main()
{
    char productName[MAX_CHAR]; 
    double price;
    char reply;
    double total = 0;

    cout << fixed << showpoint << setprecision(2);
    cout << "Welcome to your shopping calculator!" << endl;

    do {
        cout << "Enter the product name: ";
        cin.get(productName, MAX_CHAR, '\n');
        cin.ignore(100, '\n');

        cout << "Enter the amount: $";
        cin >> price;
            while (!cin) {
                  cin.clear();
                  cin.ignore(100, '\n');

                  cout << "Invalid amount. Please enter the amount: $";
                  cin >> price;
            }
            cin.ignore(100, '\n');

         cout << "The product name is" << " " << productName << " "
              << " and it costs" << " " << "$" << price << endl;

         total += price;
         cout << "The total amount is " << " " << total << endl; //program needs to keep a running total

         cout << "Would you like to continue shopping? (y/n): ";
         cin >> reply;
         cin.ignore(100, '\n');

     } while ( reply == 'Y' || reply == 'y');   //the program will continue until the user wants to checkout

   pause();
   return 0;
}

 void pause()
 {
  char ch;

   cout << "Press q followed by Enter key to continue....." << endl;
   cin >> ch;
  }  

Thanks for the help!

Upvotes: 0

Views: 1827

Answers (2)

David G
David G

Reputation: 96810

You need to map the product name to the cost using std::map so that you can print the respective pairs afterwards. As for the grand total, that's stored in the variable total so printing it is trivial.

To do this, you will need to include the <map> header, as the Standard Library class std::map is defined there. Moreover, I've also included some changes to your code that should be considered. In particular, using std::string and using std::numeric_limits<...>::max() to return the constant.

#include <iostream>
#include <string>
#include <map>

int main()
{
    std::string productName; 
    double price;
    char reply;
    double total = 0;
    std::map<std::string, double> productToPrice;

    std::cout << std::fixed << std::showpoint << std::setprecision(2);
    std::cout << "Welcome to your shopping calculator!" << std::endl;

    while ((std::cin >> reply) && (reply == 'y' || reply == 'Y'))
    {
        cout << "Enter the product name: ";
        std::cin >> productName;

        cout << "Enter the amount: $";
        while (!(cin >> price))
        {
            cin.clear();
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            cout << "Invalid amount. Please enter the amount: $";

        }
        total += price;
        productToPrice.insert(std::make_pair(productName, price));

        cout << "Would you like to continue shopping? (y/n): ";
    }
    ...
}

Note the changes I made. Please use them.

To print you simply do:

typedef std::map<std::string, double>::const_iterator iter_type;
for (iter_type beg(productToPrice.begin()),
               end(productToPrice.end()); beg != end; ++beg)
{
    std::cout << beg.first << " -- " << beg.second << std::endl;
}

std::cout << "\nThe total price is: " << total;

Upvotes: 1

Vishaal Kalwani
Vishaal Kalwani

Reputation: 740

You are definitely on the right track. I think you are mixing I/O conventions in C and C++ which is causing a lot of your issues. It would be very helpful if you could elaborate on what exactly your issues are.

Carpetfizz is correct in that since you don't know the number of items at compile time, you will need to use a dynamic array with std::vector. You can learn about vectors here.

In addition, C++ has a very useful string data type that you can include with #include <string>. Using this, as well as a junk string such as string junk;, you can avoid using cin.ignore(...) and get cleaner I/O by using getline(cin, junk).

I strongly recommend doing this because creating a vector of C-strings or C-style strings is a pain, because C-style strings are actually arrays of characters, so you'd have to use std::vector<std::vector<char> > products.

Upvotes: 0

Related Questions