Solved!
This is what I wrote:
cout << setw(4) << "Students";
cout << setw(20) << "Hours Worked";
cout << setw(20) << "of Total Hours";
cout << endl;
for (int i = 0; i < students; i++)
{
cout << setw(20);
cout << names[i];
cout << setw(10) << hours[i];
cout << setw(10) << percent[i];
cout << endl;
}
But if the first name is a few characters sorter or bigger than second name, they become misaligned. How would I keep each column aligned equally?
Try something like this:
#include<iostream>
#include <iomanip>
#include<string>
using namespace std;
int main()
{
int students = 5;
string names[5] = {"a","bccc","c","d","ecsdfsdfasdasasf"};
int hours[5] = {1,2,3,4,5};
int percent[5] = {10,20,30,40,54};
string column("Students");
int maxStringSize = 0;
int sizeOfStudentColumn = column.length();
for(int i = 0; i < 5; ++i)
{
if(maxStringSize < names[i].length())
maxStringSize = names[i].length();
}
if(sizeOfStudentColumn > maxStringSize)
maxStringSize = sizeOfStudentColumn;
cout<<"max size: "<<maxStringSize<<endl;
cout << setw(4) << "Students";
cout << setw(maxStringSize + 5) << "Hours Worked";
cout << setw(20) << "of Total Hours";
cout << endl;
for (int i = 0; i < students; i++)
{
// cout << setw(20);
cout << names[i];
int diff = maxStringSize - names[i].length();
cout << setw(diff + 5 ) << hours[i];
cout << setw(20) << percent[i];
cout << endl;
}
}
Related
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] << ...
I am trying to add up all the values that have been stored into array b and have it display under the "total column" and don't know how to only have the scores add together.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int array[5][4];
int sum = 0;
cout<<"Enter grades for 4 exams for the 5 students \n";
for(int i=0;i<5;i++)
{
for(int b=1;b<=4;b++)
{
cout <<setw(8)<< "enter student "<< i << "'s grade for exam " << b << '\n';
cin >> array[i][b];
}
}
cout <<"ID"<<setw(11)<<"score 1"<<setw(11)<<"score 2"<<setw(11)<<"score 3"<<setw(11)<<"score 4"<<setw(11)<<"total"<<setw(11)<<"letter"<<endl;
cout <<"--------------------------------------------------------------------------------------------------------------\n";
for(int i=0;i<5;i++)
{
cout << i<< " ";
for(int b=1;b<=4;b++)
{
sum = sum + array[b];
cout <<setw(10)<<array[i][b]<<sum;
}
cout <<'\n';
}
cout <<"--------------------------------------------------------------------------------------------------------------\n";
return 0;
}
To be more specific around line 28
for(int i=0;i<5;i++)
{
cout << i<< " ";
for(int b=1;b<=4;b++)
{
sum = sum + array[b];
cout <<setw(10)<<array[i][b]<<sum;
}
cout <<'\n';
Arrays indexes start at 0, not 1. You are correctly looping through your array's 1st dimension, but not its 2nd dimension. You need to change the inner for loops from for(int b=1;b<=4;b++) to for(int b=0;b<4;b++)
Also, to handle the total column, you simply need to reset sum to 0 on each iteration of the 1st dimension, and then print the result after the iteration of the 2nd dimension.
Try this:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int array[5][4];
cout << "Enter grades for 4 exams for the 5 students \n";
for(int i = 0; i < 5; i++)
{
for(int b = 0; b < 4; b++)
{
cout << "Enter student " << i+1 << "'s grade for exam " << b+1 << '\n';
cin >> array[i][b];
}
}
cout << "ID" << setw(11) << "score 1" << setw(11) << "score 2" << setw(11) << "score 3" << setw(11) << "score 4" << setw(11) << "total" << setw(11) << "letter" << endl;
cout << "--------------------------------------------------------------------------------------------------------------\n";
for(int i = 0; i < 5; i++)
{
cout << setw(2) << left << i+1 << right;
int sum = 0;
for(int b = 0; b < 4; b++)
{
sum = sum + array[i][b];
cout << setw(11) << array[i][b];
}
cout << setw(11) << sum << '\n';
}
cout << "--------------------------------------------------------------------------------------------------------------\n";
return 0;
}
Online Demo
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
I am working with a dynamic declaration of a 3 dimensional array of type CString. (I know, why CString again? Use vectors! I can't, the assignment requires use of cstring.)
So the assignment is to make a user defined playlist of songs which allows adding, removing, displaying, and searching. Also, the playlist must save to a text file called songs.txt.
My problem is I keep getting memory leaks in my adding function I will share all code and memory leak errors, so you can see.
Valgrind Errors:
==17401== HEAP SUMMARY:
==17401== in use at exit: 73,519 bytes in 31 blocks
==17401== total heap usage: 36 allocs, 5 frees, 91,199 bytes allocated
==17401==
==17401== 1 bytes in 1 blocks are definitely lost in loss record 1 of 12
==17401== at 0x4C284B7: operator new[](unsigned long) (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==17401== by 0x401BB3: songlist::readList(std::basic_ifstream<char,
std::char_traits<char> >&)
The rest just kind of repeats itself through 12 of 12
My code:
defs.cpp:
#includes <iostream>
#include <cstring>
#include <iomanip>
#include <fstream>
#include "proj4.h"
using namespace std;
void songlist::makeList()
{
MAX_TRAX = 0;
song = new char**[20];
for (int i=0; i<20; i++)
{
song[i] = new char*[5];
}
}
void songlist::readList(ifstream& infile)
{
int counter = 0;
if (!infile.is_open())
{
cout << "Cannot open file: songs.txt";
}
while(!infile.eof())
{
infile >> newSong.title >> newSong.artist >>
newSong.durationMin >> newSong.durationSec >> newSong.album;
int i = strlen(newSong.title);
i++;
int j = strlen(newSong.artist);
j++;
int k = strlen(newSong.durationMin);
k++;
int l = strlen(newSong.durationSec);
l++;
int m = strlen(newSong.album);
m++;
if(i>0)
{
song[counter][0]= new char[i];
song[counter][1]= new char[j];
song[counter][2]= new char[k];
song[counter][3]= new char[l];
song[counter][4]= new char[m];
song[counter][0] = newSong.title;
song[counter][1] = newSong.artist;
song[counter][2] = newSong.durationMin;
song[counter][3] = newSong.durationSec;
song[counter][4] = newSong.album;
counter++;
}
MAX_TRAX = counter-1;
}
counter = 0;
}
void songlist::saveList(ofstream& outfile)
{
if (!outfile.is_open())
{
cout << "Cannot find file: songs.txt";
}
for (int i=0; i<=MAX_TRAX; i++)
{
outfile << song[i][0] << "; " << song[i][1] << "; " << song[i]
[2] << "; " <<song[i][3] << "; " << song[i][4] << ";" << endl;
}
}
void songlist::displayList()const
{
cout << left << setw(16) << '#' << left << setw(30) << "Song Name" <<
left << setw(22) << "Artist Name" << left << setw(17) << "Duration" <<
left << setw(20) << "Album Title" << endl;
cout << left << setw(110) << setfill ('-') << '-' << endl;
cout << setfill (' ');
if (strlen(newSong.title)>=1)
{
for (int i=0; i<=MAX_TRAX; i++)
{
cout << left << setw(4) << i+1 << left << setw(31) <<
song[i][0] << left << setw(31) << song[i][1] << right << setw(4) << song[i]
[2]
<< ':';
if (strlen(song[i][3])==1)
{
cout << '0';
cout << left << setw(3) << song[i][3] <<
left << setw(3) << song[i][4] << endl;
}
else
cout << left << setw(4) << song[i][3] << left <<
setw(3) << song[i][4] << endl;
}
cout << left << setw(110) << setfill ('-') << '-' << endl;
cout << setfill (' ');
}
}
void songlist::addSong()
{
if(strlen(newSong.title)>=1)
{
MAX_TRAX++;
}
cout << "Add a Song" << endl;
cout << endl;
cout << "Enter Song Title: ";
cin.ignore();
cin.get(newSong.title, 30);
cout << endl;
cout << "Enter Artist Name: ";
cin.ignore();
cin.get(newSong.artist, 30);
cout << endl;
cout << "Enter Track Duration";
cout << endl;
cout << "Minutes: ";
cin.ignore();
cin.get(newSong.durationMin, 3);
cout << endl;
cout << "Seconds: ";
cin.ignore();
cin.get(newSong.durationSec, 3);
cout << endl;
cout << "Enter Album Title: ";
cin.ignore();
cin.get(newSong.album, 30);
cout << endl;
cout << "Song Added to Database!";
cout << endl;
cout << endl;
int i = strlen(newSong.title);
i++;
int j = strlen(newSong.artist);
j++;
int k = strlen(newSong.durationMin);
k++;
int l = strlen(newSong.durationSec);
l++;
int m = strlen(newSong.album);
m++;
song[MAX_TRAX][0]= new char[i];
song[MAX_TRAX][1]= new char[j];
song[MAX_TRAX][2]= new char[k];
song[MAX_TRAX][3]= new char[l];
song[MAX_TRAX][4]= new char[m];
song[MAX_TRAX][0] = newSong.title;
song[MAX_TRAX][1] = newSong.artist;
song[MAX_TRAX][2] = newSong.durationMin;
song[MAX_TRAX][3] = newSong.durationSec;
song[MAX_TRAX][4] = newSong.album;
}
void songlist::removeSong()
{
int p = 0;
int q = 0;
int n = 0;
cout << "Remove a Song" << endl;
cout << "Enter Track Number to Confirm Deletion: ";
cin >> n;
cout << endl;
while (!(n >=1 && n <= MAX_TRAX+1))
{
cin.clear();
cin.ignore();
cout << "Must be a number between 1 and " << MAX_TRAX+1 << endl;
cout << "Enter Track Number to Confirm Deletion: ";
cin >> n;
cout << endl;
}
n--;
for (p=n;p<MAX_TRAX; p++)
{
for(q=0;q<5;q++)
{
delete[] song[p][q];
}
int i = strlen(song[p+1][0]);
i++;
int j = strlen(song[p+1][1]);
j++;
int k = strlen(song[p+1][2]);
k++;
int l = strlen(song[p+1][3]);
l++;
int m = strlen(song[p+1][4]);
m++;
song[p][0] = new char[i];
song[p][1] = new char[j];
song[p][2] = new char[k];
song[p][3] = new char[l];
song[p][4] = new char[m];
song[p][0] = song[p+1][0];
song[p][1] = song[p+1][0];
song[p][2] = song[p+1][0];
song[p][3] = song[p+1][0];
song[p][4] = song[p+1][0];
}
MAX_TRAX--;
n++;
cout << "Track Number " << n << " Deleted" << endl;
}
void songlist::searchList()const
{
int i;
char aOrB;
int counter = 0;
char art[30];
char alb[30];
cout << "Search by (a)rtist or al(b)um? (a or b): ";
cin >> aOrB;
cout << endl;
if (aOrB != 'a' && aOrB != 'b')
{
cout << "(a or b): ";
cin >> aOrB;
cout << endl;
}
if (aOrB == 'a')
{
cout << "Artist Name: ";
cin.ignore();
cin.get(art, 30);
for(i=0; i<=(MAX_TRAX); i++)
{
if (strcmp(art, song[i][1])==0)
{
cout << left << setw(2) << i+1 << left <<
setw(32) << song[i][0] << left << setw(32) << song[i][1] << right << setw(4)
<< song[i][2] << ':' << left << setw(5) << song[i][3] << left << setw(32) <<
song[i][4] << endl;
counter++;
}
}
}
else
{
cout << "Album Name: ";
cin.ignore();
cin.get(alb, 30);
for(i=0; i<=(MAX_TRAX); i++)
{
if (strcmp(alb, song[i][4])==0)
{
cout << left << setw(2) << i+1 << left <<
setw(32) << song[i][0] << left << setw(32) << song[i][1] << right << setw(4)
<<
song[i][2] << ':' << left << setw(5) << song[i][3] << left << setw(32) <<
song[i][4] << endl;
counter++;
}
}
}
if (!counter)
{
cout << endl;
cout << "No Matches Found; check spelling and/or case." << endl;
}
}
void songlist::deleteAll()
{
for(int i=0; i>=20; i++)
{
for (int j=0; j<5; j++)
delete[] song[i][j];
delete[] song[i];
}
delete[] song;
}
songlist::songlist()
{
}
Proj4.h:
#ifndef PROJ3_H
#define PROJ3_H
#include <iostream>
#include <fstream>
#include <cstring>
#include <iomanip>
using namespace std;
class songlist
{
public:
void readList(ifstream& infile);
void saveList(ofstream& outfile);
void displayList() const;
void makeList();
void addSong();
void removeSong();
void searchList() const;
void deleteAll();
songlist();
private:
struct songs
{
char title[30] = {'\0'};
char artist[30] = {'\0'};
int intMin = 0;
int intSec = 0;
char durationMin[3] = {'\0'};
char durationSec[3] = {'\0'};
char album[30] = {'\0'};
};
songs newSong;
int MAX_TRAX;
char *** song;
};
#endif
app.cpp:
#include <iostream>
#include <cstring>
#include <iomanip>
#include <fstream>
#include "proj4.h"
using namespace std;
int main()
{
char selection;
cout << endl;
cout << "*Music Track Database*" << endl;
ifstream infile;
ofstream outfile;
infile.open("songs.txt");
outfile.open("songs.txt");
songlist newlist;
newlist.makeList();
do
{
cout << endl;
cout << "Main Menu:" << endl;
cout << endl;
cout << "(a)dd a song" << endl;
cout << "(r)emove a song" << endl;
cout << "(d)isplay track listings" << endl;
cout << "(s)earch for a track" << endl;
cout << "(q)uit" << endl;
cout << endl;
cout << "Select (a, r, d, s, q): ";
cin >> selection;
cout << endl;
if (selection != 'a' && selection != 'r' && selection != 'd'
&& selection != 's' && selection != 'q')
{
cout << "Select (a, r, d, s, q): ";
cin >> selection;
cout << endl;
}
switch (selection)
{
case 'a':
newlist.readList(infile);
newlist.addSong();
newlist.saveList(outfile);
break;
case 'd':
newlist.readList(infile);
newlist.displayList();
break;
case 'r':
newlist.removeSong();
newlist.saveList(outfile);
break;
case 's':
newlist.readList(infile);
newlist.searchList();
break;
}
}while (selection != 'q');
newlist.deleteAll();
cout << "Happy Trails To You; Until We Meet Again!" << endl;
cout << endl;
infile.close();
outfile.close();
return 0;
}
Also here is a simple makefile to test it:
all:
g++ app.cpp proj4.h defs.cpp -o proj4;
clean:
clean make;
Anything helps!
Thank You in advance.
You're not even allowed to use structs or classes? When you become a three star programmer it's usually very bad.
Your allocations are off by one (null termination...)
But the actual leak is here. Just think what this does:
song[p][0] = new char[i];
song[p][1] = new char[j];
song[p][2] = new char[k];
song[p][3] = new char[l];
song[p][4] = new char[m];
song[p][0] = song[p+1][0];
song[p][1] = song[p+1][0];
song[p][2] = song[p+1][0];
song[p][3] = song[p+1][0];
song[p][4] = song[p+1][0];
You first allocate memory and then throw the pointers away by assigning something else to those pointers. You can never get them back and that's a leak.
Instead of this:
song[counter][0] = new char[i];
song[counter][1] = new char[j];
song[counter][2] = new char[k];
song[counter][3] = new char[l];
song[counter][4] = new char[m];
song[counter][0] = newSong.title;
song[counter][1] = newSong.artist;
song[counter][2] = newSong.durationMin;
song[counter][3] = newSong.durationSec;
song[counter][4] = newSong.album;
Maybe Something more like:
song[counter][0] = new char[i];
song[counter][1] = new char[j];
song[counter][2] = new char[k];
song[counter][3] = new char[l];
song[counter][4] = new char[m];
strncpy(song[counter][0], newSong.title, i);
strncpy(song[counter][0], newSong.artist, j);
strncpy(song[counter][0], newSong.durationMin, k);
strncpy(song[counter][0], newSong.durationSec, l);
strncpy(song[counter][0], newSong.album, m);
This program seems to work fine until it goes to display the data after the sort function, it will display by destination but it bypasses displaying by airline. Then it gives the access violation window and I'm not 100% sure on what it even means. If anybody could explain and help that would be much appreciated.
#include <iostream>
#include <string>
using namespace std;
double flight_number[3], number_passengers[3], max_records, max_pass, min_pass;
string airline_name[3], destination[3], duplicate[3];
char reply, swapping;
int row, index[3];
void setup();
void load_arrays();
void display_airline();
void display_destination();
void sort();
int main()
{
setup();
load_arrays();
display_airline();
display_destination();
system("pause");
return 0;
}
void setup()
{
max_records = 3;
max_pass = 275;
min_pass = 50;
}
void load_arrays()
{
for (row = 0; row < max_records; row++)
{
cout << "Charter Number " << row << endl << endl;
cout << "Please enter..." << endl;
cout << "Airline Name----> ";
cin >> airline_name[row];
cout << endl;
cout << "Flight Number----> ";
cin >> flight_number[row];
cout << endl;
cout << "Destination----> ";
cin >> destination[row];
cout << endl;
cout << "Passenger Load----> ";
cin >> number_passengers[row];
cout << endl;
while (number_passengers[row] < min_pass || number_passengers[row] > max_pass)
{
cout << "You have entered an invalid amount of passengers." << endl;
cout << "There must be between 50 and 275 passengers. > ";
cin >> number_passengers[row];
cout << endl;
}
}
}
void display_airline()
{
system("cls");
for (row = 0; row < max_records; row++)
{
duplicate[row] = airline_name[row];
}
sort();
cout << "Airline" << " Flight" << " Destination" << " Passenger" << endl;
cout << "Name" << " Number" << " Load" << endl;
for (row = 0; row < max_records; row++)
{
cout << airline_name[index[row]] << " " << flight_number[index[row]] << " " << destination[index[row]] << " " << number_passengers[index[row]];
cout << endl;
}
}
void display_destination()
{
system("cls");
for (row = 0; row < max_records; row++)
{
duplicate[row] = destination[row];
}
sort();
cout << "Destination" << " Flight" << " Flight" << " Passenger" << endl;
cout << " Name" << " Number" << " Load" << endl;
for (row = 0; row < max_records; row++)
{
cout << destination[index[row]] << " " << airline_name[index[row]] << " " << flight_number[index[row]] << " " << number_passengers[index[row]];
cout << endl;
}
}
void sort()
{
for (row = 0; row < max_records; row++)
{
index[row] = row;
}
swapping = 'Y';
while (swapping == 'Y')
{
swapping = 'N';
for (row = 0; row < max_records; row++)
{
if (duplicate[row] > duplicate[row + 1])
{
swap (duplicate[row], duplicate[row + 1]);
swap (index[row], index[row + 1]);
swapping = 'Y';
}
}
}
}
also this is the full violation error: Unhandled exception at 0x009984F6 in Program 6.exe: 0xC0000005: Access violation reading location 0x03947188.
for (row = 0; row < max_records; row++)
if (duplicate[row] > duplicate[row + 1]).
What's duplicate[row+1] when row==3? You want the sort to go to max_records-1 since it works on pairs of elements rather than individual elements.