Printing floats with setw and setprecision - output doesn't line up - c++

I'm trying to print matrix in C++ using std::cout, but I have no idea how to do this correct.
I tried such variants as setw() and setprecision(), but still not achived desired appearance(You can see it on the bottom of this question).
Matrix.cpp
template<class T>
class Matrix
{
public:
...
void print(int precision=5);
...
private:
size_t rows;
size_t cols;
std::vector<T> data;
};
template<class T>
void Matrix<T>::print(int precision)
{
for (int i = 0; i < (int)this->rows; i++) {
for (int j = 0; j < (int)this->cols; j++) {
//cout << ... << " ";
}
cout << endl;
}
cout << endl;
}
Main.cpp
...
int main()
{
...
matrix.print(4);
...
}
Some attempts:
cout << data.at(i*cols + j) << " ";
Output:
-21.4269 -11.9088 -14.8804 -11.1715 3.77597
16.1763 10.68 7.99879 -0.849034 -11.9758
15.7518 -19.1033 6.27838 -3.86534 21.4716
cout << fixed << data.at(i*cols + j) << " ";
Output:
-21.426937 -11.908819 -14.880438 -11.171500 3.775967
16.176332 10.679954 7.998794 -0.849034 -11.975848
15.751815 -19.103265 6.278383 -3.865339 21.471623
Here I'm trying to use setprecision()
cout << setprecision(precision) << data.at(i*cols + j) << " ";
Output:
-21.43 -11.91 -14.88 -11.17 3.776
16.18 10.68 7.999 -0.849 -11.98
15.75 -19.1 6.278 -3.865 21.47
cout << setprecision(precision) << fixed << data.at(i*cols + j) << " ";
Output:
-21.4269 -11.9088 -14.8804 -11.1715 3.7760
16.1763 10.6800 7.9988 -0.8490 -11.9758
15.7518 -19.1033 6.2784 -3.8653 21.4716
And here I'm using setw()
cout << setw(precision) << data.at(i*cols + j) << " ";
Output:
-21.4269 -11.9088 -14.8804 -11.1715 3.77597
16.1763 10.68 7.99879 -0.849034 -11.9758
15.7518 -19.1033 6.27838 -3.86534 21.4716
cout << setw(precision) << fixed << data.at(i*cols + j) << " ";
Output:
-21.426937 -11.908819 -14.880438 -11.171500 3.775967
16.176332 10.679954 7.998794 -0.849034 -11.975848
15.751815 -19.103265 6.278383 -3.865339 21.471623
And what I really need:
-21.42 -11.91 -14.88 -11.17 3.7760
16.176 10.680 7.9988 -0.849 -11.98
15.752 -19.10 6.2784 -3.865 21.472

It turns that I just need to call function with bigger argument:
cout << setw(10) << fixed << data.at(i*cols + j) << " ";
Output:
-21.426937 -11.908819 -14.880438 -11.171500 3.775967
16.176332 10.679954 7.998794 -0.849034 -11.975848
15.751815 -19.103265 6.278383 -3.865339 21.471623
And yes, answer under link that provided #Andy is even better because it more customizable.

Related

cargo transportation system we are not sure how to display the last part of our task

Here is our code for the task we are almost finishing just the last part we are stuck at
"Fastest: 3 trips (1 Van, 3 Mini-lorry, $645) "
we are not sure how to display the values in the bracket we only able to display 3 trips.
Is there a way to also display the values in the bracket stated as well?
we use
int min = *min_element(vTrips.begin(), vTrips.end());
cout << "Fastest: " << min << " trips" << endl;
but this only display the 3 trips.
#include <iostream>
#include <vector>
#include <iterator>
#include <fstream>
#include<algorithm>
using namespace std;
class CTS //cargo transport system
{
int i;
int cargo, lorryprice, vanprice, lorrysize, vansize, allOps;
public:
void set_cargo(int);
void set_lorryprice(int);
void set_vanprice(int);
void set_lorrysize(int);
void set_vansize(int);
};
void CTS::set_cargo(int total_cargo) {
cargo = total_cargo;
}
void CTS::set_lorryprice(int lorryP) {
lorryprice = lorryP;
}
void CTS::set_vanprice(int vanP) {
vanprice = vanP;
}
void CTS::set_lorrysize(int lorryS) {
lorrysize = lorryS;
}
void CTS::set_vansize(int vanS)
{
vansize = vanS;
}
int main()
{
int cargo, lorryprice, vanprice, lorrysize, vansize, options, i, no_lorry, no_van, cost, trips;
ifstream infile;
infile.open("size.txt");
if (infile.is_open()) {
infile >> cargo;
infile >> lorryprice;
infile >> vanprice;
infile >> lorrysize;
infile >> vansize;
}
CTS run;
run.set_cargo(cargo);
run.set_lorryprice(lorryprice);
run.set_vanprice(vanprice);
run.set_lorrysize(lorrysize);
run.set_vansize(vansize);
infile.close();
options = (cargo / lorrysize) + 1;
no_lorry = (cargo / lorrysize);
no_van = (cargo / vansize) + 3;
if (cargo % lorrysize == 0) {
no_van = -3;
}
if (cargo % lorrysize != 0) {
no_van = ((cargo % lorrysize) / 10) - 3;
}
/*it = numbervan.begin();
for (auto ir = numbervan.rbegin(); ir != numbervan.rend(); ++ir) {
cout << *ir << endl;
}*/
vector<int> vCost, vVan, vTrips, vLorry;
vector <int>::iterator it;
for (i = 1; i < options + 1; i++)
{
int numberlorry = no_lorry;
cout << "Option " << i << ":" << endl;
cout << "Number of Mini-Lorries : " << no_lorry-- << endl;
if (no_van >= -3) {
no_van += 3;
}
cout << "Number of Vans : " << no_van << endl;
int numbervan = no_van;
if (numberlorry > numbervan) {
trips = numberlorry;
}
else {
trips = numbervan;
}
cout << "Trips Needed : " << trips << endl;
cost = (numberlorry * lorryprice) + (no_van * vanprice);
cout << "Total Cost : $" << cost << endl;
vCost.push_back(cost);
vLorry.push_back(numberlorry);
vVan.push_back(numbervan);
vTrips.push_back(trips);
}
int counter = vCost.size() - 1;
//std::vector<int>::reverse_iterator ir = vCost.rbegin();
for (i = 1; i < 4; i++) {
//cout << "Lowest #" << i << ": "<<cost<<endl;
cout << "Lowest #" << i << ": $" << vCost[counter] << "(" << vVan[counter] << " Vans, " << vLorry[counter] << " Mini-Lorry, " << vTrips[counter] << " Trips)" << endl;
counter--;
}
int min = *min_element(vTrips.begin(), vTrips.end()); // this line of code we figured out how to
cout << "Fastest: " << min << " trips" << endl; //display the number of trips using algorithm
return 0;
}
Your design is awkward; you create an instance of CTS run; and never use it.
Assuming that you do your calculations right, you need to know at what index you found min. If you store the iterator returned by min_element(), you can get an index by subtracting vTrips.begin() from it. Then the corresponding elements in your vCost, vLorry and vVan vectors will contain the data you want.
However, it would be easier if you define a struct containing your pre-calculated values, and push that into some vector. In that case, all related data is kept together.

Program does not terminate

In the following code, when run using GNU GCC v8.2.0, code does not terminate:
int main(void)
{
/* code */
int myArray[] = {2, 4};
int otherArray[] = {777, 888};
for(int i = 0; i<4; i++)
{
myArray[i] = 0;
cout << "myArray[" << i << "]=";
cout << myArray[i] << endl;
cout << "add: " << &myArray[i] << endl;
}
for(int i = 0; i<2; i++)
{
cout << "otherArray[" << i << "]=";
cout << otherArray[i] << endl;
cout << "add: " << &otherArray[i] << endl;
}
return 0;
}
output:
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]=0
add:0x28ff24
myarray[2]=0
add:0x28ff28
myarray[0]=0
add:0x28ff20
myarray[1]^C
for(int i = 0; i<4; i++)
Replace the 4 in the 'for loop' by 2 like this:
for(int i = 0; i<2; i++)
Since you're using a static array so it's better to specify the fixed size, but the most important is to be aware when you try to access the array by comparing the index being processed with the size of the array to avoid this behavior.
You are invoking undefined behaviour by writing the indexes 0-3 of the 2 element array myArray.
As this is undefined behaviour there are no guarantees as to what is happening or what will happen if you run the code again in the future. A likely explanation for your observed behaviour is that when you write myArray[2] that is actually overwriting the value of i causing your loop to restart back at 0.
The simple solution is to make myArray larger or change your for loop limit to 2.
To detect this sort of behaviour use std::array instead and call the at function which has bounds checking and will throw an exception when you go outside the bounds of the array. e.g.:
#include <array>
#include <iostream>
int main(void)
{
/* code */
std::array< int, 2 > myArray = { 2, 4 };
std::array< int, 2 > otherArray = { 777, 888 };
for(int i = 0; i<4; i++)
{
myArray.at(i) = 0;
std::cout << "myArray[" << i << "]=";
std::cout << myArray[i] << "\n";
std::cout << "add: " << &myArray.at(i) << "\n";
}
for(int i = 0; i<2; i++)
{
std::cout << "otherArray[" << i << "]=";
std::cout << otherArray.at(i) << "\n";
std::cout << "add: " << &otherArray.at(i) << "\n";
}
return 0;
}
std::array also has the bonus of a size() method which can make your code safer too:
for(int i = 0; i<myArray.size(); i++)
{
myArray.at(i) = 0;
std::cout << "myArray[" << i << "]=";
std::cout << myArray[i] << "\n";
std::cout << "add: " << &myArray.at(i) << "\n";
}

Output value of array rather than memory address of array

So I've made a basic polynomial class in C++ which stores the coefficients of these polynomials dynamically on the heap. I'm currently in the process of overloading operators so that I can add/subtract polynomials together in order to simplify them etc.
However I'm getting unexpected results when I try to overload the * operator. It looks like instead of returning the value of an index in the array it is returning the position of the array.
This is my *operator method in my .cpp file:
Polynomial Polynomial::operator*(Polynomial p) {
int maxDegree = (degree)+(p.degree - 1);
int *intArray3 = new int[maxDegree];
int i, j;
for (int i = 0; i < degree; i++) {
for (int j = 0; j < p.degree; j++) {
cout << getCoef(i) << " * " << p.getCoef(j) << " = " << getCoef(i)*p.getCoef(j) << endl;
intArray3[j] += (getCoef(i))*(p.getCoef(j));
cout << " intArray3[" << j << "] contains : " << intArray3[j] << endl;
}
}
return Polynomial(maxDegree, intArray3);}
The lines:
cout << getCoef(i) << " * " << p.getCoef(j) << " = " << getCoef(i)*p.getCoef(j) << endl;
and
cout << " intArray3[" << j << "] contains : " << intArray3[j] << endl;
return
10 * 1 = 10
intArray3[0] contains : -842150441
in my console. I'm assuming that the problem lies with my use of pointers somewhere but I can't for the life of me think why. I implemented this overload in a similar way to my + and - overloads and they work fine. Any assistance would be greatly appreciated. Cheers.

Reading a matrix created using an operator

Hello stackoverflow community. I need some help with a bit of code (I am a new to C++ so be gentle). I am trying to use operator() to create a matrix, store data from an input file, then write to an output file. The below code has been simplified a bit. The header file is as follows:
//Data Header File
#ifndef Data_h
#define Data_h
#include <iostream>
using namespace std;
class Data
{
private:
int d_elems;
int rows_, cols_;
int dataRows;
int *p;
public:
//Constructor
femData();
femData(int Row, int Col);
//Copy Constructor
//femData(const int d_elems);
//Destructor
virtual ~femData();
//Operator
int& operator() (int Rows, int Cols);
//Functions
void readData(istream &inp); //Read Data from Input File
void writeData(ostream &out); //Write Data from Output File
};
#endif
Any my .cpp file:
//.cpp file
#include "stdafx.h"
#include "Data.h"
#include <fstream>
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
Data::Data() {} //Blanket Constructor
Data::Data(int Row, int Col) //Matrix Constructor
: rows_ (Row), cols_ (Col)
{
if (Row == 0 || Col == 0)
{
cout << "\nMatrix is Zero..." << endl;
system("pause");
exit(0);
}
p = new int[Row * Col];
}
int& Data::operator()(int Rows, int Cols) //Operator for Matrix
{
if (Rows >= rows_ || Cols >= cols_)
{
cout << "\nMatrix subscript out of bounds\n";
system("pause");
exit(0);
}
return p[cols_ * Rows + Cols];
}
Data::~Data() { /*delete[] p;*/} //Destructor
void Data::readData(istream &inp)
{
inp >> dataRows;
int e_id;
//Data (dataRows, 10); //How would I call this constructor?
rows_ = dataRows;
cols_ = 10;
for (int i = 0; i < dataRows; i++)
{
inp >> e_id;
if ((e_id - 1) != i)
{
cout << "\nError Reading Data..." << endl;
cout << "Program Will End\n!" << endl;
system("pause");
exit(0);
}
(*this)(i, 0) = d_eid;
for (int j = 1; j < 10; j++)
{
inp >> (*this)(i, j);
}
}
void femData::writeData(ostream & out)
{
//Output Info
out << setfill('-') << setw(90) << "-" << endl;
out << setfill(' ') << setw(34) << " Matrix Information " << endl;
out << setfill('-') << setw(90) << "-" << "\n\n" << endl;
out << setfill(' ');
out << setw(10) << "ID";
out << setw(10) << "Data 1";
out << setw(10) << "Data 2";
out << setw(10) << "Data 3";
out << setw(10) << "Data 4";
out << setw(10) << "Data 5";
out << setw(10) << "Data 6";
out << setw(10) << "Data 7";
out << setw(10) << "Data 8" << endl;
for (int i = 0; i < dataRows; i++)
{
out << setw(7) << ((p + i) + 0);
out << setw(10) << ((p + i) + 1);
out << setw(10) << ((p + i) + 2);
out << setw(10) << ((p + i) + 3);
out << setw(10) << ((p + i) + 4);
out << setw(10) << ((p + i) + 5);
out << setw(10) << ((p + i) + 6);
out << setw(10) << ((p + i) + 7);
out << setw(10) << ((p + i) + 8) << endl;
//Note ((p + i) + 8) is omitted
}
}
The issue I am having is with the output. When the WriteData function is called, it writes to an output file, but does not write the data it read. Instead all that is written is {0 1 2 3 4 5 6 7 8} {1 2 3 4 5 6 7 8 9} {etc.} where {is used here to denote different rows}
Additionally, if I try to output d_elems(i,0) instead of ((d_elems + i) + 0) the compiler tells me I need a pointer to function type.
Any help would be much appreciated, thanks.
Your readData is wrong. You read data in a local object, Data d_data(dataRows,10); which is then destroyed at the end of the function. You are not filling in the data on your current instance. You need to read directly into `p'
inp >> p[i * rows_ + j];
or use the operator() you defined on the current instance, like
inp >> (*this)(i,j); // this is preferable
Side issue: you are missing the declaration of p in the class header file, int *p;.
Side issue 2: Your int& Data::operator()(int Rows, int Cols) is confusing, try using int& Data::operator()(int i, int j), and return p[i * _cols + j]; as it makes it much easier to read.

Histogram Formatting

I am writing a program to create a horizontal histogram from an array of type double data. I was able to get the program to display the boundaries of each sub-interval along with the correct number of asterisks. However, the data is not formatted.
Here's the part of the program responsible for the output:
// endpoints == the boundaries of each sub-interval
// frequency == the number of values which occur in a given sub-interval
for (int i = 0; i < count - 1; i++)
{
cout << setprecision(2) << fixed;
cout << endPoints[i] << " to " << endPoints[i + 1] << ": ";
for (int j = frequency[i]; j > 0; j--)
{
cout << "*";
}
cout << " (" << frequency[i] << ")" << endl;
}
Here's what my output looks like:
0.00 to 3.90: *** (3)
3.90 to 7.80: * (1)
7.80 to 11.70: * (1)
11.70 to 15.60: (0)
15.60 to 19.50: ***** (5)
Here's what I would like it to look like:
00.00 to 04.00: *** (3)
04.00 to 08.00: * (1)
08.00 to 12.00: * (1)
12.00 to 16.00: (0)
16.00 to 20.00: ****** (6)
I've looked up C++ syntax and have found things like setw() and setprecision(). I tried to use both to format my histogram but have not been able to make it look like the model. I was hoping someone could tell me if I'm on the right track and, if so, how to implement setw() and/or setprecision() to properly format my histogram.
Assuming that all numbers are in the [0,100) interval, what you want is a chain of manipulators like:
#include <iostream>
#include <iomanip>
int main() {
std::cout
<< std::setfill('0') << std::setw(5)
<< std::setprecision(2) << std::fixed
<< 2.0
<< std::endl;
return 0;
}
Which will output:
02.00
This is for a single value, you can easily adapt it to suit your needs.
You could, for instance, turn this into an operator and use it like:
#include <iostream>
#include <iomanip>
class FixedDouble {
public:
FixedDouble(double v): value(v) {}
const double value;
}
std::ostream & operator<< (std::ostream & stream, const FixedDouble &number) {
stream
<< std::setfill('0') << std::setw(5)
<< std::setprecision(2) << std::fixed
<< number.value
<< std::endl;
return stream;
}
int main() {
//...
for (int i = 0; i < count - 1; i++) {
std::cout
<< FixedDouble(endPoints[i])
<< " to "
<< FixedDouble(endPoints[i + 1])
<< ": ";
}
for (int j = frequency[i]; j > 0; j--) {
std::cout << "*";
}
std::cout << " (" << frequency[i] << ")" << std::endl;
//...
}