Formatting output (inputted by the user) in columns - c++

I am working on a shopping cart project, and I want to print out the user input like the following output. I don't know how to use setW and right/left keywords, when it comes to the user decides what the output is going to be like. So when they enter different inputs in length, for example setW(20) does not work for them all.
Here is your order:
----------------------------------------------------------------
Name Unit_Price Quantity
T-shirt $19.99 2
Sweater $39.99 1
iphone_case $25.5 3
Towel $9.99 5
The total charge is $206.42
----------------------------------------------------------------
This is the display function:
ostream& operator <<(ostream& os, Item& source) {
os << source.getName() << setw(18)
<< source.getPrice() << setw(20) << source.getQuantity() << endl;
return os;
}
And this is the output I get with this:
Here is your order:
----------------------------------------
NAME PRICE QUANTITY
tshirt 19.99 2
sweater 39.99 1
iphone_case 25.5 3
towel 9.99 5
The total price of the order is 206.42
----------------------------------------
And here is my main.cpp
#include "ShoppingCart.h"
#include "Item.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
cout << endl << endl << "Welcome to XXX SHOPPING CENTER" << endl;
Item items[10];
ShoppingCart<Item> cart;
char userAnswer;
cout << "Enter the item you selected as the following order:\nname unitPrice quantity\n"
<< "(Name can not contain any space. Otherwise errors happen!)" << endl;
cin >> items[0];
cart.add(items[0]);
cout << "Want to continue? y/n" << endl;
cin >> userAnswer;
int index = 1;
while(userAnswer == 'y' || userAnswer == 'Y') {
cout << "Enter the next item:" << endl;
cin >> items[index];
cart.add(items[index]);
cout << "Want to continue? y/n" << endl;
cin >> userAnswer;
index++;
}
// Display the summary of the orders
cout << endl << "Here is your order:" << endl;
// "--------------------------------------------------------------------"
for(int i=0; i < 40; i++)
cout << "-";
cout << endl << "NAME" << setw(18) << "PRICE" << setw(20) << "QUANTITY" << endl;
for(int i=0; i < cart.getCurrentSize(); i++) {
cout << items[i];
}
cout << endl << "The total price of the order is " << cart.getTotalPrice() << endl;
// "---------------------------------------------------------------------"
for(int i=0; i < 40; i++)
cout << "-";
cout << endl;
return 0;
}

The strategy you are using does not make sense to me. Here's one way to get the desired output:
Use 20 characters for the first column and make sure that it is output with left aligned text.
Use 10 characters for the second and third columns, and make sure they are output with right aligned text.
Use std::left and std::right to control text alignment.
Here's a simplified program that demonstrates the idea.
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
struct Item
{
std::string name;
double price;
int quantity;
};
std::ostream& operator<<(std::ostream& out, Item const& item)
{
// First column
out << std::left << std::setw(20) << item.name;
// Second and third columns
out << std::right << std::setw(10) << item.price << std::setw(10) << item.quantity;
return out;
}
void printLine(std::ostream& out)
{
for(int i=0; i < 40; i++)
out << "-";
out << std::endl;
}
int main()
{
std::vector<Item> items;
items.push_back({"tshirt", 19.99, 2});
items.push_back({"sweater", 39.99, 1});
items.push_back({"iphone_case", 25.50, 3});
items.push_back({"towel", 9.99, 5});
printLine(std::cout);
// First column
std::cout << std::left << std::setw(20) << "NAME"
// Second and third columns
std::cout << std::right << std::setw(10) << "PRICE" << std::setw(10) << "QUANTITY" << std::endl;
// The items
for(int i=0; i < 4; i++) {
std::cout << items[i] << std::endl;
}
printLine(std::cout);
}
Output:
----------------------------------------
NAME PRICE QUANTITY
tshirt 19.99 2
sweater 39.99 1
iphone_case 25.5 3
towel 9.99 5
----------------------------------------

Related

How do I align my output when a word is too long?

I am trying to create a program where the user enters 5 candidates for an election along with their number of votes. The program's output creates a table where it shows each candidates name, their votes, percentage of votes, and the winner of the election. My code is below and a sample of the output is in a picture that I have uploaded.
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <conio.h>
using namespace std;
const int numofcandidates = 5;
// declare variables and arrays
string candidateName[numofcandidates] = { "" };
int candidatevotes[numofcandidates];
float totalvotepercentage;
// declare methods
void takeNameandVote();
void printTable();
int main()
{
takeNameandVote();
printTable();
}
void takeNameandVote()
{
for (int i = 0; i < numofcandidates; i++)
{
cout << "Enter last name for candidate " << i + 1 << ": ";
cin >> candidateName[i];
cout << "Enter number of votes for this candidate: ";
cin >> candidatevotes[i];
}
}
void printTable()
{
// to set up % of total votes
int totalvotes = 0;
for (int i = 0; i < numofcandidates; i++)
{
totalvotes += candidatevotes[i];
}
cout << "Candidate\tVotes Received\t\t" << '%' << " of Total Votes" << endl;
for (int i = 0; i < numofcandidates; i++)
{
cout << candidateName[i] << '\t' << setw(18) << candidatevotes[i] << "\t" << fixed << showpoint << setprecision(2) << setw(16) << (candidatevotes[i] / (double)totalvotes * 100) << endl;
}
cout << "Total\t\t" << setw(10) << totalvotes << endl;
cout << endl;
}
Remove all \ts and only use std::setw:
std::cout << std::left << std::setw(18) << candidateName[i]
<< std::right << std::setw(8) << candidatevotes[i] << ...

Multiplying elements in array not working in c++?

I am trying to make a simple program in c++ that takes the price and number of items purchases, stores it in arrays, and then outputs the totals for each item in a tabular format. However, when I multiply the numbers in my code, I get totally strange answers! Can someone please enlighten me as to what's going on?
Code:
#include <iostream>
using namespace std;
int main(int argc, _TCHAR* argv[]) {
float price[4], tot[4];
int amt[4];
cout << "Please enter the price and amount of 4 items:\n";
for (int i = 0; i<4; i++) {
cout << "Price of item " << i + 1 << ": ";
cin >> price[i];
cout << "Amount of item " << i + 1 << ": ";
cin >> amt[i];
if (price[i] <= 0 || amt[i] <= 0) {
cout << "Invalid Input Entry!\n";
break;
}
tot[i] = price[i] * amt[i]; // I can't really see how I could have messed this up...
}
cout << "Total\t\tPrice\t\tAmount\n";
cout << "-----\t\t-----\t\t------\n";
for (int i = 0; i < 4; i++) {
cout << "$" << fixed << cout.precision(2) << tot[i] << "\t\t$" << price[i] << "\t\t" << amt[i] << endl;
}
system("pause");
return 0;
}
Output:
The problem is that you are outputting the return value of cout.precision(2) (which returns the previous precision, in this case 6 initially and then 2 afterwards) in front of each total price.
You need to either:
not pass the return value of cout.precision() to operator<<:
cout << "$" << fixed;
cout.precision(2);
cout << tot[i] << ...
or, call precision() one time before entering the loop:
cout.precision(2);
for (int i = 0; i < 4; i++) {
cout << "$" << fixed << tot[i] << "\t\t$" << price[i] << "\t\t" << amt[i] << endl;
}
use the std::setprecision() stream manipulator instead of calling cout.precision() directly:
#include <iomanip>
for (int i = 0; i < 4; i++) {
cout << "$" << fixed << setprecision(2) << tot[i] << "\t\t$" << price[i] << "\t\t" << amt[i] << endl;
}
or
#include <iomanip>
cout << setprecision(2);
for (int i = 0; i < 4; i++) {
cout << "$" << fixed << tot[i] << "\t\t$" << price[i] << "\t\t" << amt[i] << endl;
}
On a side note, you should not use \t characters to control the formatting of your table. Use stream manipulators like std::setw(), std::left, etc instead:
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cstdlib>
using namespace std;
const int maxItems = 4;
string moneyStr(float amount)
{
ostringstream oss;
// in C++11 and later, you can replace this with std::put_money() instead:
// http://en.cppreference.com/w/cpp/io/manip/put_money
//
// oss << showbase << put_money(amount);
oss << "$" << fixed << setprecision(2) << amount;
return oss.str();
}
int main(int argc, _TCHAR* argv[])
{
float price[maxItems], tot[maxItems];
int amt[maxItems];
int cnt = 0;
cout << "Please enter the price and amount of " << maxItems << " items:" << endl;
for (int i = 0; i < maxItems; ++i)
{
cout << "Price of item " << i + 1 << ": ";
cin >> price[i];
cout << "Amount of item " << i + 1 << ": ";
cin >> amt[i];
if (price[i] <= 0 || amt[i] <= 0) {
cout << "Invalid Input Entry!" << endl;
break;
}
tot[i] = price[i] * amt[i];
++cnt;
}
cout << left << setfill(' ');
cout << setw(16) << "Total" << setw(16) << "Price" << setw(16) << "Amount" << endl;
cout << setw(16) << "-----" << setw(16) << "-----" << setw(16) << "------" << endl;
for (int i = 0; i < cnt; i++) {
cout << setw(16) << moneyStr(tot[i]) << setw(16) << moneyStr(price[i]) << setw(16) << amt[i] << endl;
}
system("pause");
return 0;
}
Live Demo

C++ Program need help to debug

#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
using namespace std;
struct football_game
{
string visit_team;
int home_score;
int visit_score;
};
void printMenu();
int main()
{
int i, totalValues = 0;
ifstream inputFile;
string temp = "";
inputFile.open("games.txt");
if (!inputFile)
{
cout << "Error opening Input file!" << endl;
exit(101);
}
inputFile >> totalValues;
getline(inputFile, temp);
cout << " *** Football Game Scores *** " << endl << endl;
cout << " * Total Number of teams : " << totalValues << endl << endl;
football_game* records = new football_game[totalValues];
// while (!inputFile.eof())
// {// == NULL) {
for (i = 0; i < totalValues; i++)
{
getline(inputFile, records[i].visit_team);
cout << records[i].visit_team << endl;
inputFile >> records[i].home_score >> records[i].visit_score;
cout << records[i].home_score << " " << records[i].visit_score << endl;
getline(inputFile, temp);
}
//}
cout << endl;
int choice = 0;
int avg_home_Score = 0;
int avg_visit_Score = 0;
printMenu(); // prints menu
cout << "Please Enter a choice from the Menu : ";
cin >> choice;
cout << endl << endl;
while (true)
{
switch (choice)
{
case 1:
cout << " Score Table " << endl;
cout << " ***********************" << endl << endl;
cout << " VISIT_TEAM"
<< " "
<< " HIGH_SCORE"
<< " "
<< "VISIT_SCORE " << endl;
cout << " -----------"
<< " "
<< "-----------"
<< " "
<< "------------" << endl;
for (int i = 0; i < totalValues; i++)
{
cout << '|' << setw(18) << left << records[i].visit_team << " " << '|'
<< setw(7) << right << records[i].home_score << " " << '|' << setw(7)
<< right << records[i].visit_score << " " << '|' << endl;
}
cout << endl << endl << endl;
break;
case 2:
{
string team_name;
cout << "Enter the Team Name : ";
cin >> team_name;
for (int i = 0; i < totalValues; i++)
{
if (records[i].visit_team == team_name)
{
cout << " VISIT_TEAM"
<< " "
<< " HIGH_SCORE"
<< " "
<< "VISIT_SCORE " << endl;
cout << " -----------"
<< " "
<< "-----------"
<< " "
<< "------------" << endl;
cout << '|' << setw(18) << left << records[i].visit_team << " " << '|'
<< setw(7) << right << records[i].home_score << " " << '|'
<< setw(7) << right << records[i].visit_score << " " << '|'
<< endl;
}
}
cout << endl;
break;
}
case 3:
{
for (int i = 0; i < totalValues; i++)
avg_home_Score += records[i].home_score;
cout << "Average home_score: " << (avg_home_Score / totalValues) << endl << endl;
break;
}
case 4:
{
for (int i = 0; i < totalValues; i++)
avg_visit_Score += records[i].visit_score;
cout << "Average visit_score: " << (avg_visit_Score / totalValues) << endl << endl;
break;
}
default:
{
cout << "Please enter valid input !!" << endl;
break;
}
}
printMenu();
cin >> choice;
}
return 0;
}
void printMenu()
{
cout << " Menu Options " << endl;
cout << " ================ " << endl;
cout << " 1. Print Information of all Games[Table Form] " << endl;
cout << " 2. Print Information of a Specific Game " << endl;
cout << " 3. Print Average points scored by the Home Team during season" << endl;
cout << " 4. Print Average points scored against the Home Team" << endl << endl << endl;
}
Here is the input file i am using
games.txt
5
SD Mines
21 17
Northern State
10 3
BYU
10 21
Creighton
14 7
Sam Houston State
14 24
When i am using the 2nd option (Print Information of a Specific Game) from the output screen,
it ask me to enter the team name and when i enter the team-name.
For example: SD Mines it gives me an error, but when I enter the team-name with no space like: BYU it works fine for me.
cin >> team_name;
Takes the input only upto space.
You might want to use cin.getline() for taking space separated strings as input.
A small program demonstrating the same :
#include <iostream>
#include <string>
int main ()
{
std::string name;
std::cout << "Please, enter your full name: ";
std::getline (std::cin,name);
std::cout << "Name is : , " << name << "!\n";
return 0;
}
std::cin ignores whitespaces by default.
To include spaces in your input try :
getline(cin, team_name);
This would pick up all the characters in a line until you press enter. This is available in
#include<string>
You need to flush the std::cin buffer after reading the choice:
#include <limits>
//...
cin >> choice;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Refer to this question for detailed explanation.
Also, if you want to read strings with spaces from the standard input, replace this:
cin >> team_name;
with this:
getline(cin, team_name);
as already mentioned in other answers. No need to flush std::cin this time, since you have already read the full line.
Finally, remove extra newlines from your games.txt:
5
SD Mines
21 17
Northern State
...

How to get the sum of 3 columns of existing output using <iomanip>

I'v wrote a program for class which uses a for loop to have the user enter a values and it gives you a table with a loop counter, show number entered, and product. I'm trying to get the sum of All 10 numbers in each column to display at the end of each. I'm rather confused how to sum each column and display it underneath. Any help would be GREAT! I'm using Visual Studio Express 2012
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int input;
cout << "Enter Value: ";
cin >> input;
cout << "Loop Counter" << setw(20) << "Number Entered" << setw(14) << "Product" << endl;
for(int counter = 1; counter <= 10; counter++)
{
int product = input * counter;
if (product < 10 && counter != 10)
cout << setw(6) << counter << setw(17) << input << setw(17) << product << endl;
else if (product > 10 && counter != 10)
cout << setw(6) << counter << setw(17) << input << setw(18) << product << endl;
else
cout << setw(7) << counter << setw(16) << input << setw(18) << product << endl;
}
cout<<setfill('_')<<setw(45)<<"_"<<endl;
}
You'll need to sum up the column values in separate variables. Change your code like this:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int input = 0;
cout << "Enter Value: ";
cin >> input;
cout << "Loop Counter" << setw(20) << "Number Entered" << setw(14) << "Product" << endl;
int counterSum = 0;
int inputSum = 0;
int productSum = 0;
for(int counter = 1; counter <= 10; counter++) {
int product = input * counter;
if (product < 10 && counter != 10)
cout << setw(6) << counter << setw(17) << input << setw(17) << product << endl;
else if (product > 10 && counter != 10)
cout << setw(6) << counter << setw(17) << input << setw(18) << product << endl;
else
cout << setw(7) << counter << setw(16) << input << setw(18) << product << endl;
counterSum += counter;
inputSum += input;
productSum += product;
}
cout<<setfill('_')<<setw(45)<<"_"<<endl;
cout << setfill(' ') << setw(7) << counterSum << setw(16) << inputSum << setw(18) << productSum << endl;
}

Creating Table headers?

OK, in this program I am required to make a table based of user input. The problem is I cannot figure out how to get the table headers to properly align with the information that is displayed. The table headers would not line up from lets say if the user enters in Michael for player one and Michael Jordan for player 2. Any advice to allow the headers to properly align with the displayed input regardless of character length would be greatly appreciated, thanks.
Here is my code:
#include <iostream>
#include <string>
#include <iomanip>
#include <cstdlib>
using namespace std;
//struct of Basketball Player info
struct BasketballPlayerInfo
{
string name; //player name
int playerNum, //player number
pointsScored; //points scored
};
int main()
{
int index, //loop count
total = 0; //hold total points
const int numPlayers = 5; //nuymber of players
BasketballPlayerInfo players[numPlayers]; //Array of players
//ask user for Basketball Player Info
cout << "Enter the name, number, and points scored for each of the 5 players.\n";
for (index = 0; index < numPlayers; index++)
{
//collect player name
cout << " " << endl;
cout << "Enter the name of player # " << (index + 1);
cout << ": ";
//input validation
if(!(getline(cin, players[index].name)))
{
cout << "Player Name must be alphabetical characters only!\n";
cout << "Program terminating please start over." << endl;
system("pause");
exit(0);
}
//getline(cin, players[index].name);
//collect players number
cout << "Enter the number of player # " << (index + 1);
cout << ": ";
//input validation
if(!(cin >> players[index].playerNum))
{
cout << "Player Name must be numeric characters only!\n";
cout << "Program terminating please start over." << endl;
system("pause");
exit(0);
}
//collect points scored
cout << "Enter points scored for player # " << (index + 1);
cout << ": ";
//input validation
if(!(cin >> players[index].pointsScored))
{
cout << "Player Name must be numeric characters only!\n";
cout << "Program terminating please start over." << endl;
system("pause");
exit(0);
}
cin.ignore();
}
//display
cout << "\n";
cout << "Here is the information for each player: \n";
cout << fixed << showpoint << setprecision(2);
cout << "\n";
cout << " \tName\tNumber\tPoints\n";
cout << "------------------------------------------------" << endl;
for(index = 0; index < numPlayers; index++)
{
cout << "Player # " << (index + 1);
cout << ": \t" << players[index].name << "\t" << players[index].playerNum << "\t" << players[index].pointsScored << endl;
cout << "------------------------------------------------" << endl;
}
//display total points scored by all players
for(index = 0; index < numPlayers; index++)
{
//hold total
total += players[index].pointsScored;
}
cout << "Total Points scored are: " << total << endl;
system("pause");
return 0;
}
you could use setw io manipulator which comes under #include <iomanip>.
cout << setw(20) << "Column1"
<< setw(20) << "Column2"
<< setw(8) << "Column3";
or you could use Boost library
// using Boost.Format
cout << format("%-20s %-20s %-8s\n") % "Column1" % "Column2" % "Column3";
Take a look at the setw and setfill functions. You can use them to assign a minimum width to your columns, which will make for much cleaner output formatting than tabs.