Is there a way to exclude a value from set precision? - c++

How would I modify code, like the code shown below, to exclude the constant VALUE_1 when using setprecision(2) so that it will display 3 decimals instead of 2 like the others?
#include <iostream>
#include <iomanip>
using namespace std;
const double VALUE_1 = .011;
int main(void)
{
double value2;
double value3;
value2 = 2.362;
value3 = 5;
cout << fixed << setprecision(2);
cout << value2 << endl;
cout << VALUE_1 << endl;
cout << value3 << endl;
return 0;
}
I tried the following fix and it works fine, but is there anything else that doesn't look so improvised? Or is this the intended method?
cout << value_2 << endl;
cout << setprecision (3) << value_1 << endl;
cout << setprecision (2) << value_3 << endl;

I would probably do it by writing my own manipulator to at least combine the steps of setting fixed format and the width I wanted:
class fixed {
int width;
public:
fixed(int width) : width(width) {}
friend std::ostream &operator<<(std::ostream &os, fixed const &f) {
return os << std::fixed << std::setw(width);
}
};
Then you'd write out your numbers like:
std::cout << fixed(3) << value2 << '\n'
<< fixed(2) << VALUE_1 << '\n'
<< fixed(2) << value3 << '\n';
Admittedly, not a drastic improvement, but seems at least a little better to me.
Oh and avoid std::endl unless you really need it (which is pretty much never).

Related

What is C++ equivalent of ā€œ%-[width]sā€ for cout stream? [duplicate]

In a C++ code I have a matrix of double variables which I print out. However because all of them have different number of digits, the output format is destroyed. One solution is to do
cout.precision(5) but I want different columns have a different precision. Also, because there are negative values in some cases, the presence of the - sign also causes problems. How to get around this and produce a properly formatted output?
Off the top of my head, you can use setw(int) to specify the width of the output.
like this:
std::cout << std::setw(5) << 0.2 << std::setw(10) << 123456 << std::endl;
std::cout << std::setw(5) << 0.12 << std::setw(10) << 123456789 << std::endl;
gives this:
0.2 123456
0.12 123456789
The key is, as others have said, to use manipulators. What they
neglected to say is that you normally use manipulators that you write
yourself. An FFmt manipulator (which corresponds to the F format in
Fortran is fairly easy:
class FFmt
{
int myWidth;
int myPrecision;
public:
FFmt( int width, int precision )
: myWidth( width )
, myPrecision( precision )
{
}
friend std::ostream&
operator<<( std::ostream& dest, FFmt const& fmt )
{
dest.setf( std::ios_base::fixed, std::ios_base::formatfield );
dest.precision( myPrecision );
dest.width( myWidth );
return dest;
}
};
This way, you can define a variable for each column, say:
FFmt col1( 8, 2 );
FFmt col2( 6, 3 );
// ...
and write:
std::cout << col1 << value1
<< ' ' << col2 << value2...
In general, except in the simplest programs, you should probably not be
using the standard manipulators, but rather custom manipulators based on
your application; e.g. temperature and pressure if that's the sort of
thing your dealing with. In this way, it's clear in the code what
you're formatting, and if the client suddenly asks for one more digit in
the pressure, you know exactly where to make the change.
Use manipulators.
From sample here:
#include <iostream>
#include <iomanip>
#include <locale>
int main()
{
std::cout.imbue(std::locale("en_US.utf8"));
std::cout << "Left fill:\n" << std::left << std::setfill('*')
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << std::hex << std::showbase << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << "\n\n";
std::cout << "Internal fill:\n" << std::internal
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << "\n\n";
std::cout << "Right fill:\n" << std::right
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << '\n';
}
Output:
Left fill:
-1.23*******
0x2a********
USD *1.23***
Internal fill:
-*******1.23
0x********2a
USD ****1.23
Right fill:
*******-1.23
********0x2a
***USD *1.23
Take a look at stream manipulators, especially std::setw and std::setfill.
float f = 3.1415926535;
std::cout << std::setprecision(5) // precision of floating point output
<< std::setfill(' ') // character used to fill the column
<< std::setw(20) // width of column
<< f << '\n'; // your number
Try using setw manipulator. Please refer http://www.cplusplus.com/reference/iostream/manipulators/setw/ for further information
There is a way using i/o manipulators, but I find it unwieldy. I would just write a function like this:
template<typename T>
std::string RightAligned(int size, const T & val)
{
std::string x = boost::lexical_cast<std::string>(val);
if (x.size() < size)
x = std::string(size - x.size(), ' ') + x;
return x;
}

How to return a variable from one function in C++ to main then use it in another function?

Okay so I have a calorie calculator that is supposed to be separated into the five functions including main seen below. My issue is that I get a compiler error because the variables from the inputNumber function and calculateCalories function cannot be read by any of the other functions once they are obtained. I am not allowed to use Global variables. There must be something I am missing to be able to read the variables within the main function then output them into the other functions to get the proper output. Any help would be appreciated.
Here is the code as it stands:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
int Lbs, hourr, hourW, hourWe, hourb;
double calBad, calRun, calWal, calWei;
string name;
cout << "Welcome to Megan McCracken's Workout Calculator!" << endl;
cout << endl;
cout << "Please enter your name: ";
getline(cin, name);
inputNumber(Lbs, hourr, hourW, hourWe, hourb);
calculateCalories(Lbs,hourr,hourb,hourW,hourWe,calBad,calRun,calWal,calWei);
displayHeadings(name);
displayLine(hourr,hourb,hourW,hourWe,calBad,calRun,calWal,calWei);
system("pause");
return 0;
}
int inputNumber(int Lbs, int hourr, int hourb, int hourW, int hourWe)
{
cout << "Please enter your weight: ";
cin >> Lbs;
return Lbs;
cout << "Please enter the minutes spent playing badminton: ";
cin >> hourb;
return hourb;
cout << "Please enter the minutes spent running: ";
cin >> hourr;
return hourr;
cout << "Please enter the minutes spent walking: ";
cin >> hourW;
return hourW;
cout << "Please enter the minutes spent lifting weights: ";
cin >> hourWe;
return hourWe;
cout << endl;
}
double calculateCalories(int Lbs, int hourW, int hourb, int hourr, int hourWe, double calBad, double calRun, double calWal, double calWei)
{
const double Badburn = .044, Runburn = .087, Walkb = .036, Weightb = .042;
double calBad, calRun, calWal, calWei;
calBad = (Badburn * Lbs) * hourb;
calRun = (Runburn * Lbs) * hourr;
calWal = (Walkb * Lbs) * hourW;
calWei = (Weightb * Lbs) * hourWe;
return calBad;
return calRun;
return calWal;
return calWei;
}
void displayHeadings(string name)
{
cout << "Here are the results for " << name << ": " << endl;
cout << endl;
cout << "Activity" << right << setw(18) << "Time" << right << setw(10) << "Calories" << endl;
cout << "--------------------------------------" << endl;
}
void displayLine(int hourb,int hourr, int hourW, int hourWe, double calBad, double calRun, double calWal, double calWei)
{
int HB, MB, HR, MR, HW, MW, HWE, MWE, Hour, Min;
double Calorie;
HB = (hourb / 60);
MB = (hourb % 60);
HR = (hourr / 60);
MR = (hourr % 60);
HW = (hourW / 60);
MW = (hourW % 60);
HWE = (hourWe / 60);
MWE = (hourWe % 60);
Calorie = calBad + calRun + calWal + calWei;
Hour = (hourb + hourr + hourW + hourWe) / 60;
Min = (hourb + hourr + hourW + hourWe) % 60;
cout << "Badminton" << right << setw(14) << HB << ":" << setfill('0') << setw(2) << MB << setfill(' ') << right << setw(10) << setprecision(3) << fixed << showpoint << calBad << endl;
cout << resetiosflags(ios::fixed | ios::showpoint);
cout << "Running" << right << setw(16) << HR << ":" << setfill('0') << setw(2) << MR << setfill(' ') << right << setw(10) << setprecision(3) << fixed << showpoint << calRun << endl;
cout << resetiosflags(ios::fixed | ios::showpoint);
cout << "Walking" << right << setw(16) << HW << ":" << setfill('0') << setw(2) << MW << setfill(' ') << right << setw(10) << setprecision(3) << fixed << showpoint << calWal << endl;
cout << resetiosflags(ios::fixed | ios::showpoint);
cout << "Weights" << right << setw(16) << HWE << ":" << setfill('0') << setw(2) << MWE << setfill(' ') << right << setw(10) << setprecision(3) << fixed << showpoint << calWei << endl;
cout << "--------------------------------------" << endl;
cout << resetiosflags(ios::fixed | ios::showpoint);
cout << "Totals" << right << setw(17) << Hour << ":" << setfill('0') << setw(2) << Min << setfill(' ') << right << setw(10) << setprecision(3) << fixed << showpoint << Calorie << endl;
cout << endl;
}
If you want to modify passed-in variables within a function in C++, you should be passing them in by reference (default is by value, meaning you get a copy of the variable which is effectively thrown away when the function exits).
So, by way of example:
void xyzzy (int plugh) { plugh = 42; }
int main() {
int twisty = 7;
xyzzy (twisty);
cout << twisty << '\n';
return 0;
}
will output 7 because twisty was passed by value and changes to it within the function will not be echoed back to the caller.
However, if you pass by reference with:
void xyzzy (int &plugh) { plugh = 42; }
// ^
// This does the trick.
then you'll find it outputs 42 as desired.
For your particular case, you want to look at the variables in the argument list of inputNumber:
int inputNumber(int Lbs, int hourr, int hourb, int hourW, int hourWe)
Any of these that you want echoed back to the caller (and that looks like all of them from a cursory glance) should be pass by reference rather than pass by value.
You should also look into calculateCalories as well, since that is doing the same thing. Keep in mind that only the ones you want to change and echo back to the caller need to be pass-by-reference. So that's only the ones starting with cal.
And, since you're using the pass-by-reference to modify the variables, there's absolutely no reason to return anything from that function so it can be specified as void calculateCalories ... and the return statements removed (in any case, only the first return would have actually done anything, the others would have been unreachable code).
If you haven't yet got to the point where you can use references in your classwork (as seems to be indicated by one of your comments), you can do what C coders have been doing for decades, emulating pass-by-reference with pointers. In terms of the simplified example above, that would mean modifying the function to receive a pointer to the item you want changed, changing what it points to, and calling it with the address of the variable to be changed:
void xyzzy (int *pPlugh) { *pPlugh = 42; }
int main() {
int twisty = 7;
xyzzy (&twisty);
cout << twisty << '\n';
return 0;
}
However, it's a poor substitute for the real thing and, if your educator is trying to teach you that, it's the same as if they're getting you to use printf/scanf rather than cout/cin for user I/O: it's certainly possible in C++ since the language includes legacy C stuff, but it's not really teaching you the C++ way.
People who claim to be C++ developers but really code in C using a C++ compiler, are a rather strange breed that I like to call C+ developers - they've never really embraced the language properly. The sooner people put aside the legacy stuff, the better they'll be as C++ developers.
Pass the variables by references. Then the functions will be able to edit them.
Your other solution (not so much of a good idea but still working) is to create a struct/class and make the functions return it.
P.S. Your code won't work if the functions are in this order unless you add their signatures in the beginning:
int main();
int inputNumber(int,int,int,int,int);
//and so on
In input number, you can not use 'return' to return each value - it will do the first return statement.
In C++ you can use pass by reference so that values assigned to the variables will be passed back up.
In this case, via the input variables would be inputNumber so use '&' to denote the vaiables are references:
void inputNumber(int &Lbs, int &hourr, int &hourb, int &hourW, int &hourWe)
{
.
.
.
}
Similar idea for calculateCalories, get rid of the returns:
void calculateCalories(int Lbs, int hourW, int hourb, int hourr, int hourWe, double &calBad, double &calRun, double &calWal, double &calWei)
{
.
.
}
Note that we are only bothering to pass to reference for the variables that we will be passing back.

C++ manipulation using iomanip library

I am new to C++ STL libraries and need help.
I want to add two numbers suppose A = 4555 and B = 50, and output them as:
4555
+50
4605
Another Examples:
500000 + 12
500000
+12
500012
If i am storing both A and B in integer data type while the sign '+' in character data type. How can i manipulate them to get the preferred output.
I just cant figure out how to manipulate two variables together.
You might utilize the manipulators std::showpos, std::noshowpos and std::setw:
#include <iostream>
#include <iomanip>
int main() {
int a = 4555;
int b = 50;
std::cout
<< std::noshowpos << std::setw(10) << a << '\n'
<< std::showpos << std::setw(10) << b << '\n'
<< std::noshowpos << std::setw(10) << (a+b) << '\n';
}
If you want a width depending on the values you may use three std::ostringstream(s) and create intermediate strings (without setw). After that you print the strings using the maximal length of each for setw:
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <sstream>
int main() {
int a = 4555;
int b = 50;
std::ostringstream as;
std::ostringstream bs;
std::ostringstream rs;
as << std::noshowpos << a;
bs << std::showpos << b;
rs << std::noshowpos << (a+b);
unsigned width = std::max({ as.str().size(), bs.str().size(), rs.str().size() });
std::cout
<< std::setw(width) << as.str() << '\n'
<< std::setw(width) << bs.str() << '\n'
<< std::setw(width) << rs.str() << '\n';
}
See also:
http://www.cplusplus.com/reference/iomanip/
http://www.cplusplus.com/reference/ios/
Note: You may have a look at the manipulator std::internal.
If you could use constant width (or variable width equal to the maximum width of the numbers involved) with std::setw from <iomanip> as:
#include <iostream>
#include <iomanip>
#include <string>
void display_sum(int a, int b)
{
std::cout << std::setw(10) << a << "\n"
<< std::setw(10) << ("+" + std::to_string(b)) << "\n"
<< std::setw(10) << (a+b) <<"\n" << std::endl;
}
int main()
{
display_sum(4555, 50);
display_sum(500000, 12);
display_sum(503930, 3922);
}
Output:
4555
+50
4605
500000
+12
500012
503930
+3922
507852
Online demo
In your example the fields can fit a maximum number of 7 characters. Perhaps you want to resize the strings to 7 before writing. e.g. fname.resize(7).
To format it as you want you need to #include <iomanip> and use std::left and std::setw(7).
file1 << left << setw(7) << fname
<< tab << setw(7) << lname
<< tab << setw(7) << street
<< tab << setw(7) << city
<< tab << setw(7) << state
<< tab << setw(7) << zip << endl;

C++ int with output manipulators

I am wrecking my brain trying to figure this. Please bear with me as I'm only in my forth week into learning C++.
The code below works fine when having all the code just in the main()
int main()
{
cout << setfill('0') << setw(1) << hundreds << setw(1) << tens
<< setw(1) << units << "\n";
system("PAUSE");
return 0;
}
However I've been asked to make it work so that the code is split, but I can't seem to do it. My attempt is below. If someone could send me on the right track that would be great. Please bare in mind that we haven't learnt anything to complex so it shouldn't be hard.
int main()
{
cout << "The encrypted number is: " << recomposedEncryptedNumber() << "\n";
system("PAUSE");
return (0);
}
int recomposedEncryptedNumber()
{
return setfill('0') << setw(1) << hundreds << setw(1) << tens << setw(1) << units;
}
the expression cout << stuff has cout as return value so you need to do the same in your function:
std::ostream& recomposedEncryptedNumber()
{
return cout << setfill('0') << setw(1) << hundreds << setw(1) << tens << setw(1) << units;
}
Your initial code combines a lot on a single line. I'm breaking it apart for explanation:
int main()
{
cout // cout is "console output" -- i.e. how you print to the screen
<< setfill('0') // This is the operation "cout << setfill('0')"
// which creates a modifier "setfill", passes it to cout,
// and now you've "taught" cout to use '0' as the fill
// character.
// Importantly, "cout << setfill('0')" returns cout...
<< setw(1) // This is the operation "cout << setw(1)".
// It's applying the "<< setw(1)" to the return of the
// previous command. This is also a special modifier,
// and again, this returns 'cout'.
<< hundreds // Now you're finally printing something, because this
// is doing "cout << hundreds"
<< setw(1)
<< tens
<< setw(1)
<< units
<< "\n";
system("PAUSE");
return 0;
}
Importantly, every operation in that long line is cout << {something}, and the result of the << operation is the cout again -- which is why you can chain the statements together.
Knowing that, you should now be able to see why this fails:
int recomposedEncryptedNumber()
{
return
setfill('0') // This gives you the setfill modifier.
// -- but that's _not_ cout.
<< setw(1) // "setfill << setw"?? Not what you want at all.
// You want "cout << setfill" and "cout << setw".
<< hundreds << setw(1) << tens << setw(1) << units;
}
You have many options on how to proceed. You could do something like this:
int main() {
cout << "The encrypted number is: ";
printRecomposedEncryptedNumber();
cout << "\n";
}
These are three separate statements. Now printRecomposedEncryptedNumber can print your details to cout directly, and return void (i.e. not return anything).
If you want to do it inline:
int main() {
cout << "The encrypted number is: " << recomposedEncryptedNumber() << "\n";
}
Then your recomposedEncryptedNumber must return something that can be given to cout. Since you're trying to do some special formatting, you don't want to use int -- cout will just display the int the way it wants to. So you should use a string. Then your function can do whatever formatting it wants, and return the properly formatted string:
string recomposedEncryptedNumber(int hundreds, int tens, int units)
{
std::ostringstream msg; // 'o' is for output
// 'string' is because we're building a string
// 'stream' is because this uses streaming methods
// i.e. 'ostringstream' lets us build a string,
// by using streaming mechanisms.
// Same stream machinations you were doing before, just with 'msg'
// instead of 'cout'
msg << setfill('0') << setw(1) << hundreds << setw(1) << tens << setw(1) << units;
return msg.str(); // return the string we've built.
}
Lastly, in order for your function to access hundreds, tens, units, the function must be given those variables (i.e. the variables must be passed into the function as parameters).
Welcome to C++!
Did you declare your prototype before main? for example. I do not have more time to explain but here is how you would do it
#include <iostream>
#include <iomanip>
using namespace std;
void recomposedEncryptedNumber(int hun, int tens, int units);
int main()
{
int hun = 1;
int tens = 1;
int units = 1;
cout << "The encrypted number is: " << "\n";
recomposedEncryptedNumber(hun,tens,units);
system("PAUSE");
return (0);
}
void recomposedEncryptedNumber(int hun, int tens, int units)
{
cout << setfill('0') << setw(1) << hun << setw(1) << tens << setw(1) << units;
}`
cout print on the standard output, you're trying to mix 2 types and that's why it doesn't work.
Try it :
std::string recomposedEncryptedNumber()
{
std::string str;
concat(str,setfill('0'));
concat(str,setw(1));
...
return str;
}
Well,
thats how I would implement what I think you need:
#include <iostream>
#include <iomanip>
using namespace std;
class EncryptedNumber
{
public:
EncryptedNumber( unsigned h, unsigned t, unsigned u )
: hundreds( h ),
tens( t ),
units( u )
{}
protected:
unsigned hundreds,
tens,
units;
friend std::ostream & operator << ( std::ostream& outs, const EncryptedNumber& en );
};
std::ostream & operator << ( std::ostream& outs, const EncryptedNumber& en )
{
outs << setfill( '0' ) << setw( 1 ) << en.hundreds
<< setw( 1 ) << en.tens
<< setw( 1 ) << en.units;
return outs;
}
int main()
{
EncryptedNumber en( 1, 2, 3 );
cout << "The encrypted number is: " << en << "\n";
system("PAUSE");
return (0);
}
Of course it is a quick solution and I haven't created getter/setter methods, didn't split the concept from implementantion and nothing useful inside EncryptedNumber.
The point is that code will look far more elegant and mantainable this way.
Please tell me if you want a more detailed explanation.

Formatting output in C++

In a C++ code I have a matrix of double variables which I print out. However because all of them have different number of digits, the output format is destroyed. One solution is to do
cout.precision(5) but I want different columns have a different precision. Also, because there are negative values in some cases, the presence of the - sign also causes problems. How to get around this and produce a properly formatted output?
Off the top of my head, you can use setw(int) to specify the width of the output.
like this:
std::cout << std::setw(5) << 0.2 << std::setw(10) << 123456 << std::endl;
std::cout << std::setw(5) << 0.12 << std::setw(10) << 123456789 << std::endl;
gives this:
0.2 123456
0.12 123456789
The key is, as others have said, to use manipulators. What they
neglected to say is that you normally use manipulators that you write
yourself. An FFmt manipulator (which corresponds to the F format in
Fortran is fairly easy:
class FFmt
{
int myWidth;
int myPrecision;
public:
FFmt( int width, int precision )
: myWidth( width )
, myPrecision( precision )
{
}
friend std::ostream&
operator<<( std::ostream& dest, FFmt const& fmt )
{
dest.setf( std::ios_base::fixed, std::ios_base::formatfield );
dest.precision( myPrecision );
dest.width( myWidth );
return dest;
}
};
This way, you can define a variable for each column, say:
FFmt col1( 8, 2 );
FFmt col2( 6, 3 );
// ...
and write:
std::cout << col1 << value1
<< ' ' << col2 << value2...
In general, except in the simplest programs, you should probably not be
using the standard manipulators, but rather custom manipulators based on
your application; e.g. temperature and pressure if that's the sort of
thing your dealing with. In this way, it's clear in the code what
you're formatting, and if the client suddenly asks for one more digit in
the pressure, you know exactly where to make the change.
Use manipulators.
From sample here:
#include <iostream>
#include <iomanip>
#include <locale>
int main()
{
std::cout.imbue(std::locale("en_US.utf8"));
std::cout << "Left fill:\n" << std::left << std::setfill('*')
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << std::hex << std::showbase << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << "\n\n";
std::cout << "Internal fill:\n" << std::internal
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << "\n\n";
std::cout << "Right fill:\n" << std::right
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << 42 << '\n'
<< std::setw(12) << std::put_money(123, true) << '\n';
}
Output:
Left fill:
-1.23*******
0x2a********
USD *1.23***
Internal fill:
-*******1.23
0x********2a
USD ****1.23
Right fill:
*******-1.23
********0x2a
***USD *1.23
Take a look at stream manipulators, especially std::setw and std::setfill.
float f = 3.1415926535;
std::cout << std::setprecision(5) // precision of floating point output
<< std::setfill(' ') // character used to fill the column
<< std::setw(20) // width of column
<< f << '\n'; // your number
Try using setw manipulator. Please refer http://www.cplusplus.com/reference/iostream/manipulators/setw/ for further information
There is a way using i/o manipulators, but I find it unwieldy. I would just write a function like this:
template<typename T>
std::string RightAligned(int size, const T & val)
{
std::string x = boost::lexical_cast<std::string>(val);
if (x.size() < size)
x = std::string(size - x.size(), ' ') + x;
return x;
}