Formatting with setw() c++ - c++

I am trying to create an organized looking graph with the amount of money for each food under each month. I was able to line up the first row, but after that, something started going off. This is what I ended up with:
This is the code I tried playing around with the setw() but I can't seem to change it for the number after it puts out the first array element.
void sales_report() {
for (int i = 0; i < 7; i++) {
cout << setw(17) << months[i] << " ";
}
cout << endl << foods[0] << " ";
for (int i = 0; i < 6; i++) {
sumapple += apples[i];
cout << setprecision(2) << fixed << setw(8) << money << apples[i] << " ";
}
cout << setprecision(2) << fixed << setw(8) << money << sumapple << endl;
cout << foods[1] << " ";
for (int i = 0; i < 6; i++) {
sumoranges += oranges[i];
cout << setprecision(2) << fixed << setw(7) << money << oranges[i] << " ";
}
cout << setprecision(2) << fixed << setw(7) << money << sumoranges << endl;
cout << foods[2] << " ";
for (int i = 0; i < 6; i++) {
sumpears += pears[i];
cout << setprecision(2) << fixed << setw(10) << money << pears[i] << " ";
}
cout << setprecision(2) << fixed << setw(10) << money << sumpears << endl;
cout << foods[3] << " ";
for (int i = 0; i < 6; i++) {
sumtomatoes += tomatoes[i];
cout << setprecision(2) << fixed << setw(7) << money << tomatoes[i] << " ";
}
cout << setprecision(2) << fixed << setw(7) << money << sumtomatoes << endl;
cout << foods[4] << " ";
for (int i = 0; i < 6; i++) {
sumcherries += cherries[i];
cout << setprecision(2) << fixed << setw(6) << money << cherries[i] << " ";
}
cout << setprecision(2) << fixed << setw(6) << money << sumcherries << endl << totalmonth;
for (int i = 0; i < 6; i++) {
total = apples[i] + oranges[i] + pears[i] + tomatoes[i] + cherries[i];
cout << setprecision(2) << fixed << setw(9) << money << total << " ";
}
}

You are using different std::setw() values in each of the for loops. Hence the misalignment. Use the same values.

Related

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

Seg fault while outputting 2-d array of strings

So i have been working on this code for a while, and I am not very skilled. I have created two classes one defines an item for a shopping list, and the other creates an array of the objects and outputs them as a list. The program works in my windows command prompt, but segfaults on GNU command line when I am outputting the array using cout statements.
void List::createList(Item ** itemPtr, int size)
{
string** list1 = new string*[size];
for(int i = 0; i < 5; i++)
{
list1[i] = new string[5];
}
for (int i = 0; i < size; i++)
{
list1[i][0] = itemPtr[i]->getName();
list1[i][1] = itemPtr[i]->getUnit();
list1[i][2] = itemPtr[i]->getSTRnumToBuy();
list1[i][3] = itemPtr[i]->getSTRcost();
list1[i][4] = itemPtr[i]->getSTRextCost();
}
cout << endl << left << fixed << setw(15) << setprecision(2) << "Name";
cout << fixed << left << setw(15) << setprecision(2) << "Unit Type";
cout << fixed << left << setw(15) << setprecision(2) << "# of units";
cout << fixed << left << setw(15) << setprecision(2) << "Cost/Unit";
cout << fixed << left << setw(15) << setprecision(2) << "Total" << endl;
for (int i = 0; i < size; i++)
{
cout << fixed << left << setw(15) <<setprecision(2)<<endl<< list1[i][0];
cout << fixed << left << setw(15) << setprecision(2) << list1[i][1];
cout << fixed << left << setw(15) << setprecision(2) << list1[i][2];
cout << fixed << left << setw(15) << setprecision(2) << list1[i][3];
cout << fixed << left << setw(15) << setprecision(2) << list1[i][4];
}
}
Your 1st loop should be :
for(int i = 0; i < size; i++)
{
list1[i] = new string[5];
}
That is, loop till size, not till 5.
string** list1 = new string*[size];
for(int i = 0; i < 5; i++)
Looks like a bug to me: if size < 5 then you will be reading out of bounds of the array you have created.
list1[i][0] = itemPtr[i]->getName();
list1[i][1] = itemPtr[i]->getUnit();
list1[i][2] = itemPtr[i]->getSTRnumToBuy();
list1[i][3] = itemPtr[i]->getSTRcost();
list1[i][4] = itemPtr[i]->getSTRextCost();
This could fail if the size of the itemPtr array is less than size.
Another point, though not related to the crash you're seeing, you are leaking memory here. list1 is a local variable that's not stored somewhere in your class. You are allocating memory for it on the heap, but do not free that memory (delete) it anywhere.
Your using C++ not C so use the power of the vector
void List::createList(Item ** itemPtr, int size) {
vector<vector<string>> list1;
list1.resize(size);
for (int i = 0; i < size; i++) {
list1[i].resize(5);
list1[i][0] = itemPtr[i]->getName();
list1[i][1] = itemPtr[i]->getUnit();
list1[i][2] = itemPtr[i]->getSTRnumToBuy();
list1[i][3] = itemPtr[i]->getSTRcost();
list1[i][4] = itemPtr[i]->getSTRextCost();
}
cout << endl << left << fixed << setw(15) << setprecision(2) << "Name";
cout << fixed << left << setw(15) << setprecision(2) << "Unit Type";
cout << fixed << left << setw(15) << setprecision(2) << "# of units";
cout << fixed << left << setw(15) << setprecision(2) << "Cost/Unit";
cout << fixed << left << setw(15) << setprecision(2) << "Total" << endl;
for (int i = 0; i < size; i++)
{
cout << fixed << left << setw(15) <<setprecision(2)<<endl<< list1[i][0];
cout << fixed << left << setw(15) << setprecision(2) << list1[i][1];
cout << fixed << left << setw(15) << setprecision(2) << list1[i][2];
cout << fixed << left << setw(15) << setprecision(2) << list1[i][3];
cout << fixed << left << setw(15) << setprecision(2) << list1[i][4];
}
}
Look Ma, no news nor deletes.

How to get arrays to show up on a file?

So I have some code here that takes an array for employee id and then also fills arrays for hours worked, pay rate, etc and then displays them all. There is no trouble with this part and it all runs smoothly. However I am trying to write this data to a file, but instead of writing the data for all the employees to the file it only writes the data for one employee. I cant seem to figure out why!
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
ofstream outputFile;
const int numOfEmployees = 7;
int long empId[numOfEmployees] = { 5658845, 4520125, 7895122, 8777541, 8451277, 1302850, 7580489 };
int hours[numOfEmployees];
double payRate[numOfEmployees];
double wages[numOfEmployees];
outputFile.open("PayrollDataBackup.txt");
cout << "Enter the hours worked by 7 employees and their hourly pay rates."<<endl;
cout << " " << endl;
for (int count = 0; count < numOfEmployees; count++)
{
cout << "Hours worked by employee #" << empId[count] << ":";
cin >> hours[count];
while (hours < 0)
{
cout << "Please enter a positive number: ";
cin >> hours[count];
}
cout << "Hourly pay rate for employee #" << empId[count] << ":";
cin >> payRate[count];
while (payRate[count] < 15.00)
{
cout << "Please enter a pay rate higher than $6.00: ";
cin >> payRate[count];
}
}
cout << " " << endl;
cout << "Here are the hours worked, pay rate and gross pay for each employee:" << endl;
cout << " " << endl;
for (int count = 0; count < numOfEmployees; count++)
{
wages[count] = hours[count] * payRate[count];
cout << " " << endl;
cout << fixed << showpoint << setprecision(2);
cout <<"ID:"<< empId[count] <<" Hours: "<< hours[count] << " Pay rate: $" << payRate[count] <<" Wage: $" << wages[count] << endl;
}
for (int count = 0; count < numOfEmployees; count++)
{
outputFile << empId[count] << " " << hours[count] << " " << payRate[count] << " " << endl;
outputFile.close();
}
system("pause");
return 0;
}
You are closing the file after writing the first record.
Change:
for (int count = 0; count < numOfEmployees; count++)
{
outputFile << empId[count] << " " << hours[count] << " " << payRate[count] << " " << endl;
outputFile.close();
}
To:
for (int count = 0; count < numOfEmployees; count++)
{
outputFile << empId[count] << " " << hours[count] << " " << payRate[count] << " " << endl;
}
outputFile.close();

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;
}

C++: Append string to output of first and last array index in loop

I tried to word the title as best as I could. Here I have a function that indexes through two parallel arrays and then outputs them with some formatting.
void outputTable(string salsa_jars[], int jars_sold[], int index[])
{
int totalSold = 0;
cout << setw(8) << "\nSalsa type sells: " << endl
<< "-------------------------------" << endl;
for(int i = 0; i <= (SALSA_TYPES-1); i++)
{
totalSold += jars_sold[index[i]];
cout << setw(15) << left << salsa_jars[index[i]]
<< setw(15) << right << jars_sold[index[i]] << endl;
}
cout << "-------------------------------" << endl
<< "Total sales: " << setw(17) << totalSold << endl;
}
What I'm trying to achieve is to add a string to the first and last outputs of the array. Below is my attempt.
void outputTable(string salsa_jars[], int jars_sold[], int index[])
{
int totalSold = 0;
cout << setw(8) << "\nSalsa type sells: " << endl
<< "-------------------------------" << endl;
for(int i=0;i<=(SALSA_TYPES-1);i++)
{
if(i == 0){
cout << setw(7) << left << salsa_jars[index[i]]
<< "(Highest)" << setw(14) << right
<< jars_sold[index[i]] << endl;
}
else if (i == (SALSA_TYPES-1)){
cout << setw(7) << left << salsa_jars[index[i]]
<< "(Lowest)" << setw(15) << right
<< jars_sold[index[i]] << endl;
}
else{
totalSold += jars_sold[index[i]];
cout << setw(15) << left << salsa_jars[index[i]]
<< setw(15) << right << jars_sold[index[i]] << endl;
}
}
cout << "-------------------------------" << endl
<< "Total sales: " << setw(17) << totalSold << endl;
}
But the code seems redundant, and I couldn't think of any other way to do it. If anyone has any pointers, I would appreciate it. Thanks.
Just prepare appropriate title for entry, and use common logic for displaying it:
for(int i=0;i<=(SALSA_TYPES-1);i++)
{
string title = toString(salsa_jars[index[i]]);
if(i == 0){
title += " (Highest)";
}
else if (i == (SALSA_TYPES-1)){
title += " (Lowest)";
}
totalSold += jars_sold[index[i]];
cout << setw(15) << left << title
<< setw(15) << right << jars_sold[index[i]] << endl;
}
}