Output not aligned correctly even after using SetW - c++

I want my program to be aligned correctly; I'm using the iomanip (setw) library but I'm still getting the wrong output:
The output I want is:
1001 Butter 9.45 50 100 74
1002 Milk-1L 12.85 100 150 83
1003 Flour-Bak 13.45 210 500 410
The output I'm getting currently is:
1001 Butter 9.45 50 100 74
1002 Milk-1L 12.85 100 150 83
1003 Flour-Bak 13.45 210 500 410
Here is my code:
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;
// Function Declaration
void displaymenu();
void Inventory();
void empgrossnet();
void employavgdeduc();
// Size of Array
const int SIZE = 10;
int i;
// Initialize Struct function for Employee Data
struct InventoryData {
int Itemnum;
string Name;
double UnitPrice;
int Minimumlevel;
int Optimumlevel;
int Qtyinstock;
} InventoryItems[SIZE];
// Initialize/Read file into the program
ifstream thefile("i_Data.txt");
int main() {
while (true) {
displaymenu();
}
return 0;
}
void displaymenu() {
int option;
// print menu options and prompt user to enter a menu option
printf("\n***************** Employee Data *******************\n");
printf("[1] Press 1 for Inventory Data Records\n");
printf("[2] Press 2 for Employee Gross and Net Pay\n");
printf("[3] Press 3 for Average Hours and Average Deductions\n");
printf("[4] Exit Program\n");
printf("\n****************************************************\n");
printf("\n Enter an option>>\t");
scanf("%d", &option);
switch (option) {
case 1:
Inventory();
break;
case 4:
printf("\n\n Thank you for using the Program");
printf("\n Exiting Application....");
exit(0);
}
}
void Inventory() {
// Read from edata.txt File
ifstream thefile("i_Data.txt");
// Check to make sure that Program is finding/reading from edata file
if (!thefile) {
cerr << "File can't be opened! " << endl;
system("PAUSE");
exit(1);
}
// Creat loop to store 5 lines of information from edata file
for (int i = 0; i < SIZE; i++) {
thefile >> InventoryItems[i].Itemnum >> InventoryItems[i].Name >>
InventoryItems[i].UnitPrice
>> InventoryItems[i].Minimumlevel >> InventoryItems[i].Optimumlevel >>
InventoryItems[i].Qtyinstock;
}
// Output/Display Edata file information into prgram
printf("\n************************************* EMPLOYEE DATA "
"****************************************\n");
printf("\n %s %15s %20s %15s %15s ", "EmployeeID", "Employee Name",
"Hours Worked", "Rate of Pay", "Deductions");
printf("\n-------------------------------------------------------------------"
"------------------\n");
for (int i = 0; i < SIZE; i++) {
cout << setw(10) << " " << InventoryItems[i].Itemnum;
cout << setw(10) << " " << InventoryItems[i].Name;
cout << setw(10) << " " << InventoryItems[i].UnitPrice;
cout << setw(10) << " " << InventoryItems[i].Minimumlevel;
cout << setw(10) << " " << InventoryItems[i].Optimumlevel;
cout << setw(10) << " " << InventoryItems[i].Qtyinstock << endl;
}
printf("\n-------------------------------------------------------------------"
"------------------\n");
}

You seem to want
cout <<" " << setw(10) << InventoryItems[i].Itemnum;
cout <<" " << setw(10) << InventoryItems[i].Name;
cout <<" " << setw(10) << InventoryItems[i].UnitPrice;
cout <<" " << setw(10) << InventoryItems[i].Minimumlevel;
cout <<" " << setw(10) << InventoryItems[i].Optimumlevel;
cout <<" " << setw(10) << InventoryItems[i].Qtyinstock<<endl;
Your original code outputs 10 spaces then values. I believe you want single spaces and values in 10-char placeholders.

Related

cin doesnt take another input correctly after a set of input from while

This is the file_processing_tutor.cpp file:
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <cstdlib>
#include "ClientData.h"
using namespace std;
void outputline(int, const string &, double);
void outputlineDAT(ostream&, const ClientData &);
int main() {
cout << endl << "Phase 1 Writing Data to txt" << endl;
cout << "Make Sure Input is already ready before running" << endl;
ofstream outClientFile("C:/Users/User/Desktop/Streaming DT Data/test.txt", ios::out);
if(!outClientFile){
cerr << "File could not be opened" << endl;
exit(EXIT_FAILURE);
}
cout << "Enter the account, name, and balance" << endl << "Enter end-of-file to end input." << endl;
int count_input = 0;
int account;
string name;
double balance;
while(cin >> account >> name >> balance){
++count_input;
outClientFile << account << ' ' << name << ' ' << balance << endl;
cout << "? (Input Count = " << count_input << ") " << endl;
}
cout << endl << endl << "Phase 2 Reading Data from txt" << endl;
ifstream inClientFile("C:/Users/User/Desktop/Streaming DT Data/test.txt", ios::in);
if(!inClientFile){
cerr << "File Could not be Opened" << endl;
exit(EXIT_FAILURE);
}
cout << left << setw(10) << "Account" << setw(13) << "Name" << "Balance" << endl << fixed << showpoint;
while(inClientFile >> account >> name >> balance){
outputline(account, name, balance);
}
cout << endl << "Phase 3 Writing 100 Blank Records to Random Access File .Dat" << endl;
fstream outCredit("C:/Users/User/Desktop/Streaming DT Data/credit.dat", ios::out | ios::in | ios::binary);
if(!outCredit){
cerr << "File Could not be opened" << endl;
exit(EXIT_FAILURE);
}
ClientData blankClient;
for(int i = 0; i < 100; ++i){
outCredit.write(reinterpret_cast <const char *>(&blankClient), sizeof(ClientData));
}
cout << endl << "Phase 4 Writing Data Randomly to a Random Access File .Dat" << endl;
string firstName;
string lastName;
cout << "Enter Account Number (1 to 100, 0 to end input)\n?";
ClientData client;
cin >> account;
cout << "Account Input: " << account << endl;
while(account > 0 && account <= 100){
cout << "Enter lastname, firstname, balance \n?";
cin >> lastName >> firstName >> balance;
client.setAccountNumber(account);
client.setLastName(lastName);
client.setFirstName(firstName);
client.setBalance(balance);
outCredit.seekp((client.getAccountNumber() - 1) * sizeof(ClientData));
cout << "Enter Account Number (1 to 100, 0 to end input)\n?";
cin >> account;
}
return 0;
}
void outputline(int account, const string &name, double balance){
cout << left << setw(10) << account << setw(13) << name << setw(7)
<< setprecision(2) << right << balance << endl;
}
void outputlineDAT(ostream &output, const ClientData &record){
output << left << setw(10) << record.getAccountNumber() << setw(16)
<< record.getLastName() << setw(11) << record.getFirstName() << setw(10)
<< setprecision(2) << right << fixed << showpoint << record.getBalance() << endl;
}
Because I am using Sublime Text 3, I set my input in a file called inputf.in, this is all my raw input:
100 Jones 24.98
200 Doe 345.67
300 White 0
400 Stone -42.16
500 Rich 224.62
450 Harmond 412.5
3
Barker Doug 0
29
Brown Nancy -24.54
96
Stone Sam 34.98
88
Smith Dave 258.34
33
Dunn Stacey 314.33
0
And I see my output as follows from outputf.out:
Phase 1 Writing Data to txt
Make Sure Input is already ready before running
Enter the account, name, and balance
Enter end-of-file to end input.
? (Input Count = 1)
? (Input Count = 2)
? (Input Count = 3)
? (Input Count = 4)
? (Input Count = 5)
? (Input Count = 6)
Phase 2 Reading Data from txt
Account Name Balance
100 Jones 24.98
200 Doe 345.67
300 White 0.00
400 Stone -42.16
500 Rich 224.62
450 Harmond 412.50
Phase 3 Writing 100 Blank Records to Random Access File .Dat
Phase 4 Writing Data Randomly to a Random Access File .Dat
Enter Account Number (1 to 100, 0 to end input)
?Account Input: 450
Problem:
So every output in above was ok, until it reached phase 4 where I get to input new data for account variable, Instead of get the input 3 (which is set from the input) it reoutputs the last account data (450) ignoring the cin input. thus it didn't input anything to a file called credit.dat.
Appreciate any pointers to the issues, Thankyou!

Formatting output (inputted by the user) in columns

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

(c++) reading from a text file

I made this program that asks users to enter the grade of some students, determine whether they pass or fail and then determine how many pass and how many fail the exam. Here's my code:
#include <iostream>
using namespace std;
int main ()
{
int passing = 0;
int failing = 0;
int mid_grade;
int final_grade;
int student = 5;
while (student > 0)
{
cout << "Enter mid-term grade: ";
cin >> mid_grade;
cout << "Enter final grade: ";
cin >> final_grade;
double total_grade = (double)mid_grade*3/10 + (double)final_grade*7/10;;
cout << "The total grade is: " << total_grade << endl;
student --;
if (mid_grade < 4 || final_grade < 4 || total_grade < 10)
{
// cout << "Fail." << endl;
failing++;
}
else
{
// cout << "Pass!" << endl;
passing++;
}
}
cout << passing << " student passed" << endl;
cout << failing << " student failed" << endl;
return 0;
}
what I want to do now is to tell my program to read the mid-term and the final grade in a text file I made then calculate the total grade (like I did in the above code), then show the grades on the screen, determine who pass and fail the exam and the total number of students who pass/fail the exam.
Here's what my text file looks like:
Mid-term Final
8 5
9 6
10 11
15 17
9 20
11 19
Alright so this should help. I put some notes. You need to create a text file in the same directory /src called grades.txt
should look like this
10 9 8 7 4 3 4 5 5 9
You will need to change things. But this should give you a good starting point or where you should be going. Hope this helps.
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
int passing = 0;
int failing = 0;
int mid_grade = 0; //Always initilize your variables!!!
int final_grade = 0;
int student = 5;
//Create a variable to open the file
ifstream inFile; inFile.open("src\\grades.txt");
while (student > 0)
{
cout << "Enter mid-term grade: ";
inFile >> mid_grade;
cout << mid_grade << endl;
cout << "Enter final grade: ";
inFile >> final_grade;
cout << final_grade << endl;
cout << "student number" << student << endl; //Notice it goes backwards you have to fix it.
double total_grade = ((double)mid_grade*3)/10 + ((double)final_grade*7/10);
cout << "The total grade is: " << total_grade << endl;
student --;
cout << endl;
if (total_grade < 7)
{
// cout << "Fail." << endl;
failing++;
}
else
{
// cout << "Pass!" << endl;
passing++;
}
}`enter code here`
cout << passing << " student penter code hereassed" << endl;
cout << failing << " student failed" << endl;
return 0;
}
I'd read the file, skip the 1st line, then read the rest, line by line, using stringtokenizer to get the two values to work with.

How to use an array of structs correctly?

I'm trying to be able to call the vendingmachine function and have it give me a table of the stuff i got from the file but it gives me crazy numbers like -858993460. I have to be able to change the individual amounts and prices before calling the function so it can give me different numbers.
Cola
0.75 20
Ruby Red Blast
1.00 10
Lemon Fizz
0.75 8
Grape Soda
0.90 5
Citrus Flip
0.85 0
Habanero Surprise
0.80 11
^^This is the text file im working with
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
struct soda{
string name;
double price;
int amount;
};
void vendingmachine(struct soda[6]);
int main(){
ifstream inFile;
soda soda[6];
inFile.open ("machine.txt");
if ( inFile.fail() )
{
cout << "Error: Data file could not be opened" << endl;
exit (EXIT_FAILURE);
}
for(int i=0; i < 6; i++){
getline(inFile, soda[i].name);
inFile >> soda[i].price;
inFile >> soda[i].amount;
inFile.ignore(100,'\n');
}
cout << "Welcome to the vending machine!" << endl;
cout << endl;
vendingmachine(soda);
return 0;
}
void vendingmachine(struct soda soda[6]){
cout << "***************************************************************" << endl;
cout << " " << "Drink Name" << " " << "Price Per Can" << " " << "Number in Machine" << endl;
for( int i=0; i < 6; i++){
cout << setw(17) << soda[i].name << setw(16) << soda[i].price << setw(20) << soda[i].amount << endl;
}
cout << "***************************************************************" << endl;
}
Thanks everyone, i changed it to how it should be.
You are declaring a local variable soda and operating on that in the function
void vendingmachine(struct soda[6]){
soda soda[6];
You need to operate on the caller's array instead
void vendingmachine(struct soda soda[6]){
//soda soda[6];
Change your function to this:
void vendingmachine(struct soda soda[6]){
cout << "***************************************************************" << endl;
cout << " " << "Drink Name" << " " << "Price Per Can" << " " << "Number in Machine" << endl;
for( int i=0; i < 6; i++){
cout << setw(17) << soda[i].name << setw(16) << soda[i].price << setw(20) << soda[i].amount << endl;
}
cout << "***************************************************************" << endl;
}
THEN!
Go to your loop where you are receiving the data from the text file and type this:
cout << soda[i].name << endl;
(now run the program)
You will notice that the whole first line is attributed to the Cola then there are 5 blank lines that are printed.
Now all you need to do is make sure the variables from the text file are correctly being put into your struct and you will soon be finished.

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.