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!
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;
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.
Related
i am making a program which is supposed to collect input from the user by asking for id, name, units attempted, units earned and the gpa of a student and store that into a struct. Currently, when i input more than one student into the struct, it only outputs the last student in the array. What can i do to fix this?
Here is my code
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
struct Student {
string ID; //an 8-digit student ID
string name; //name of the student
unsigned unitsAttempted;//number of units attempted by the student
unsigned unitsEarned; //number of units earned by the student
double gpa; //the grade point average for the student
};
int main()
{
Student students[10];//array for 10 Student Structs
char answer = 'y';
int number = 0;
while ((answer == 'y') || (answer == 'Y')) {
//prompt the user to enter the data
{
answer = ' ';
int i = 0;
cout << "Enter the students ID: \n" ;
getline(cin, students[i].ID);
cout << "\nEnter the name:\n";
getline(cin, students[i].name);
cout << "\nEnter the units attempted:\n";
cin >> students[i].unitsAttempted;
cin.ignore();
cout << "\nEnter the units earned:\n";
cin >> students[i].unitsEarned;
cin.ignore();
cout << "\nEnter the GPA: \n";
cin >> students[i].gpa;
cin.ignore();
cout << "\nWould you like to add another student? y or n\n";
cin >> answer;
cin.ignore();
i++;
number++;
}
}
cout << left << setw(10) << "ID " << setw(20) <<"Name" << setw(20) <<"Units Attempted" << setw(20) <<"Units Earned" << setw(10) <<"GPA";
cout << "\n===============================================================\n";
for (int i = 0; i < number; i++)//display the students
{
cout << left << setw(10) << students[i].ID << setw(20) << students[i].name << setw(20) <<students[i].unitsAttempted << setw(20) <<students[i].unitsEarned << setw(10) <<students[i].gpa << endl << endl;
}
return 0;
}
Im still learning so please go easy on me, thanks.
Currently, when i input more than one student into the struct, it only outputs the last student in the array.
It looks most likely that the scope of your i is incorrect:
int i = 0; //<-- this should be declared outside the `while` loop
As it stands, your i is scoped inside while loop, so it will be reset every time the while loop is entered. In other word, that i never increased.
I want to read strings with white spaces into members of a structure. Tried using getline but both the output statements are clubbed with a single cin for both. As per the similar posts here, tried using cin.ignore, but the input is not read into the member of the structure. Pls help. It's a part of my assignment and I'm a beginner in C++. This is how my code looks like:
#include <string.h>
using namespace std;
struct book {
string title, author;
int no_of_pages, year;
float price;
};
int main() {
int N;
cout << "Enter the no. of books whose details are to be entered:" << endl;
cin >> N;
book b[N];
int x;
for (x = 0; x < N; x++) {
cout << "Enter the title of book #" << x + 1 << ":" << endl;
getline(cin, (b[x].title));
// cin.ignore();
cin.ignore(1000, '\n');
cout << "Enter the author's name:" << endl;
getline(cin, (b[x].author));
cout << "Enter the no. of pages:" << endl;
cin >> b[x].no_of_pages;
cout << "Enter the price of book:" << endl;
cin >> b[x].price;
cout << "Enter the year of publishing" << endl;
cin >> b[x].year;
}
for (x = 0; x < N; x++) {
cout << "\n\n";
cout << "The details of book" << x + 1 << " are:" << endl;
cout << "Title :" << b[x].title << endl;
cout << "Author :" << b[x].author << endl;
cout << "No. of pages :" << b[x].no_of_pages << endl;
cout << "Price :" << b[x].price << endl;
cout << "Publishing year:" << b[x].year << endl;
cout << "---------------------------------------------";
}
return 0;
}
There's no point in using cin.ignore() in between two calls to getline. ignore is used to discard remaining characters after numeric input. So the place to use it is after numeric input and before the next getline. Like this
cout << "Enter the title of book #" << x + 1 << ":" << endl;
getline(cin, (b[x].title));
cout << "Enter the author's name:" << endl;
getline(cin, (b[x].author));
cout << "Enter the no. of pages:" << endl;
cin >> b[x].no_of_pages;
cout << "Enter the price of book:" << endl;
cin >> b[x].price;
cout << "Enter the year of publishing" << endl;
cin >> b[x].year;
cin.ignore(1000, '\n');
That said I would just read everything using getline, then convert the strings to numbers where needed. That's simpler and cleaner, all you need to know is how to convert a string to an integer, which you can easily research for yourself.
There are two places you should put cin.ignore in your code:
cout << "Enter the no. of books whose details are to be entered:" << endl;
cin >> N;
// First cin.ignore here
cin.ignore(1000, '\n');
cout << "Enter the year of publishing" << endl;
cin >> b[x].year;
// Second cin.ignore here
cin.ignore(1000, '\n');
Besides this I see two more problems in your code:
#include <string> not <string.h>
add #include <iostream>
Why cin.ignore is necessary? User is expected to provide new line ('\n') delimited input. When getline is used, it leaves the input stream in such a state that the next attempt to read input from stream will start at next line. This is not true for operator >>. What int x; cin >> x; does here is it reads only the integer not the new line character present right after the integer. Hence, the next attempt to read will continue within the same line. getline will then find no character before new line and hence will fetch an empty string. To avoid this and to effectively start reading from the next line, cin.ignore is necessary.
This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 3 years ago.
I use getline command in a while loop. The command works fine in the first loop. But after the second loop, it just passes the getline commands and doesn't allow me to enter
I tried cin.get and cin.getline but the problem is not fixed
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int price;
void addItem(){
string product;
cout << "Please enter product's name: " << endl;
getline(cin, product);
cout << "Please enter product's price: " ;
cin >> price;
cout << "You have added " << product << " with a price of $" << price << " to your cart." << endl;
}
int main() {
char answer = 'y';
int total = 0;
while (answer == 'y'){
addItem();
total += price;
cout << "Do you want to add another product (y/n)? " ;
cin >> answer;
}
if (answer != 'y'){
cout << "Your total is $" << total << endl;
}
return 0;
}
Mixing cin >> with getline(cin,...), so you should to avoid it. I assume that you used getline to read product name which contain spaces inside. You could rewrite your code to use only getline which should give you expected behavior:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int price = 0;
void addItem(){
string product{};
string price_str{};
cout << "Please enter product's name: " << endl;
getline(cin, product);
cout << "Please enter product's price: " ;
getline(cin,price_str);
/*CHECK IF price_str is number before calling stoi*/
price = stoi(price_str);
cout << "You have added " << product << " with a price of $" << price << " to your cart." << endl;
}
int main() {
string answer = "y";
int total = 0;
while (answer == "y"){
addItem();
total += price;
cout << "Do you want to add another product (y/n)? " ;
getline(cin,answer);
}
if (answer != "y"){
cout << "Your total is $" << total << endl;
}
return 0;
}
try
while(cin>>answer && answer !='y'){
cout<<"enter again \n";
}
cout<<"ok";
I am trying to subtract these two numbers, and I keep getting this error.
code:
#include <iostream>
using namespace std;
void Cal()
{
string Money = "back";
string TotPay = "back";
string Assets = "back";
cout << "At anytime, you can type the word 'back' to go back a step." << endl;
do{
cout << "Enter your total amount of money: ";
cin >> Money;
}while(Money == "back");
do{
cout << "\nEnter the total of your payments: ";
cin >> TotPay;
}while(TotPay == "back");
do{
cout << "\nEnter the total value of your assets: ";
cin >> Assets;
}while(Assets == "back");
cout << "Your net worth is " << (Money + Assets) - TotPay << "!";
}
int main()
{
string name;
string yn;
cout << "Enter your name please: ";
cin >> name;
cout << "\nHello " << name << ", today we are going to calculate your net worth.\n";
do{
Cal();
cout << "Would you like to calculate again? (yes/no)\n";
cin >> yn;
}while(yn == "yes");
cout << "See ya!";
return 0;
}
The error is on the line of code that says
cout << "Your net worth is " << (Money + Assets) - TotPay << "!";
The program will not ever compile with the subtraction sign (-) there, and if I change it to a addition sign (+) then it will compile, but the numbers will not properly add, and the end number just ends up being a place holder number for the variable (for example, 2555354 or something like that).
Am I missing something here?
Any help would be appreciated.
Although others have pointed out rightly..
To get this code working, the string values need to be treated as an integer:
cout << "Your net worth is " << (stoi(Money) + stoi(Assets)) - stoi(TotPay) << "!";
You are trying to add and subtract strings, not numbers.
While addition works (and results in string concatenation), subtracting strhings doesn't make sense. Use numbers:
int Money = 0;
int TotPay = 0;
int Assets = 0;
Depending on your applications need, you might want to use a different numeric type, e.g. double.
I have a problem with my code, every time I loop it with the answer 'y'(Yes) it loops to infinity?
I'm trying to make a loan calculator and every time the user is done calculating with a transaction and wants to reset, and do another calculation if he enters in a value 'y', and if he enters 'n' the program will end.
Here's my code so far:
#include <iostream>
#include <string>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
char ans = 'y';
do {
string name;
int Months;
int n;
double LoanAmount, Rate, MonthlyInterest, TotalLoanAmount, MonthlyAmortization, OutstandingBalance;
cout << fixed << showpoint;
cout << "Enter Name of Borrower: ";
getline(cin, name);
cout << "Enter Loan Amount: ";
cin >> LoanAmount;
cout << "Enter Number of Months to Pay: ";
cin >> Months;
cout << "Enter Interest Rate in Percent(%): ";
cin >> Rate;
cout << setprecision(2);
MonthlyInterest = LoanAmount * Rate;
TotalLoanAmount = LoanAmount + (MonthlyInterest * Months);
cout << "Monthly Interest: " << MonthlyInterest << endl
<< "Total Loan Amount with interest: " << TotalLoanAmount << endl;
cout << setw(100)
<< "\n\tSUMMARY OF OUTSTANDING INSTALLMENT" << endl
<< "\tName of Borrower: " << name
<< "\n\nMonth\t\tMonthly Amortization\t\tOutstanding Balance"
<< "\n";
for(n = 1; n <= Months; n++) {
MonthlyAmortization = TotalLoanAmount / Months;
OutstandingBalance = TotalLoanAmount - MonthlyAmortization;
cout << n << "\t\t" << MonthlyAmortization << "\t\t\t" << n - 1 << OutstandingBalance << endl;
}
cout << "\nEnd of Transaction";
cout << "Do you want to compute another transaction?[y/n]?" << endl;
cin >> ans;
}
while(ans == 'y');
}
After your cin>>ans, add these two lines :
cin.clear();
cin.sync();
That usually fixes a lot of the infinite looping problems I get with cin.
Also, I would recommend against initializing ans as 'y' when you declare it. I don't think this is causing you problems but it's an uncessesary thing.
You seem to expect pressing y and enter to register as only 'y'. If you want to get the input of just one character have a look at std::cin.get(char)