Issue when "fixed" stream manipulator is removed - c++

I am new to C++, learning it by my self, and I am using the book "C++ how to program - 7th edition" from Deitel. Now, please have a look at the following code
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
double principle = 1000;
double amount;
double rate = 0.05;
cout << "Year" << setw(21) << "Amount on deposit" << endl;
cout << fixed << setprecision(2);
for(int years=1; years<=10; years++)
{
amount = principle * pow(1.0+rate,1.0);
cout << setw(4) << years << setw(21) << amount << endl;
}
}
When I removed the "fixed" stream manipulator, the output becomes stupid, which means, just ascii letters and numbers. When I insert it, the output comes without any problem. My question is, why is this happening? Is "fixed" mandatory for all the programs which has "double" type outputs? Please help.
And another thing. What are stream manipulators? As a Java developer, I thought these might be some kind of constant variables, but it is not! They are methods? Then why the brackets are not there? Please answer to this question too.
Thanks

The output does not "become stupid": you simply let your output stream choose the format for your floating-point numbers, and it picks scientific notation. This gives you 1e+03 (which means 1*10^3) instead of 1050.00. The use of fixed tells the stream that you do not want scientific notation; you could also use scientific to force the scientific format. Since the precise format depends depends on your application requirements, the choice to use fixed or scientific is ultimately up to you.

Manipulators like fixed are functions, but if you wanted the common () for it then it would look like this:
fixed(cout); //Instead of using the << or >> you pass the stream into the manipulator function.
See this reference for more on manipulators:
http://www.cplusplus.com/reference/iostream/manipulators/
Also, fixed documentation can be found here:
http://www.cplusplus.com/reference/iostream/manipulators/fixed/
Hope this helps

It's not just ascii letter and numbers
1e+03 is scientific writing for 1*10^3 which is 1000
for reference:
http://www.cplusplus.com/reference/iostream/manipulators/fixed/

If you had chose a wider precision, your output would have been different without fixed.
cout << setprecision(6); // 6 instead of 2
Then your output would have looked more like you expected. (Incidentally, you should compute the compound interest by folding the interest earned back into the principle.)
Otherwise, with only setprecision(2), the formatter decides to use scientific notation in order to only display 2 digits of precision.
But, since you want the output to provide a fixed number of digits, what you have provided (both fixed and setprecision(2)) will do that.

Related

Concatenate float with string and round to 2 decimal places

So I have a function below formatted as polymorphic void display(string& outStr). The output from this function should basically be formatted into one large string, which will be saved to the outStr parameter and returned to the calling function.
I have successfully formatted my large string into multiple lines but I would like to round my float value to 2 decimal places but I can't figure out how with the way I'm currently appending my strings. I tried using the round() and ceil() functions as some posts online have suggested, but 6 zeros still appear after each decimal place. I would appreciate some help with this as I've been looking for solutions for a while but none of them have worked.
Additionally, I was wondering if the to_string() function I used to convert my float to a string would compile and execute correctly in C++98? I'm using C++11 but my teacher is using C++98 and I'm extremely worried that it won't compile on her end.
If not, can anyone suggest how else I could achieve the same result of turning a float into a string while still formatting multiple lines into the outStr string parameter and returning it to the function? I am not allowed to change the function's parameters, it must stay as display(string& outStr)
My output is a lot longer and complex but I simplified the example for the sake of getting a short and easy solution.
Again, I would appreciate any help!
#include <iostream>
using namespace std;
#include <string>
#include <sstream>
#include <cmath>
#include "Math.h"
void Math::display(string& outStr){
float numOne = 35;
float numTwo = 33;
string hello = "Hello, your percent is: \n";
outStr.append(hello);
string percent = "Percent: \n";
outStr.append(percent);
float numPercent = ceil(((numOne / numTwo) * 100) * 100.0) / 100.0;
outStr.append(to_string(numPercent));
outStr.append("\n");
}
Output should look like:
Hello, your percent is:
Number:
106.06%
There is no need to do any crazy conversions. Since the function is called display, my guess is that it's actually supposed to display the value instead of just save it to a string.
The following code demonstrates how that can be accomplished by just formatting your printing.
#include <cstdio>
#include <iomanip>
#include <iostream>
int main() {
double percentage = 83.1415926;
std::cout << "Raw: " << percentage << "%\n";
std::cout << "cout: " << std::fixed << std::setprecision(2) << percentage << "%\n";
printf("printf: %.2f\%%\n", percentage); // double up % to print the actual symbol
}
Output is:
Raw: 83.1416%
cout: 83.14%
printf: 83.14%
If the function is as backwards as you describe it, there are two possibilities. You don't understand what's actually required and are giving us a bad explanation (my guess given that function signature), or the assignment itself is pure garbage. As much as SO likes to rag on professors, I find it difficult to believe that what you've described and written is what the professor wants. It makes no sense.
A couple notes: there is nothing polymorhpic about the code you've shown. to_string() exists as of C++11, which is easily seen by looking up the function (Link). There is also a discrepancy between what your code attempts to print versus what your output is, and that's before we even get to the number formatting portion. "Percent" or "Number"?

setprecision applied to old C style code

I know that in C++ I can use setprecision as follows:
streamsize prec = cout.precision();
cout << "Your grade is: " << setprecision(3) << finalGrade << setprecision(prec);
How can I adapt this to the following old style code, particularly when writing to a file?
for ( int k = 0 ; k < vector.size() ; k++ )
{
fprintf( myFile, "%i\t%f\t%f\n", k+1, vector[k].x, vector[k].y );
std::cout << vector[k].x << "\t" << vector[k].y;
}
What specifically I am confused about is the order in which setprecision(3) and setprecision(prec) appear, when there is more than one variable, like in the case of vector elements being written to a file...
Could somebody please help me understand this?
Thank you,
It was not clear from the question that you want the setprecision to modify how fprintf works; it's only clear from the comments.
This is impossible (at least, with the existing C++ standard library).
The stdio and iostreams systems are separate, mostly independent parts in C++. In addition, the iostreams stuff was standardized after the stdio stuff, so to support having setprecision affect fprintf would mean changing fprintf code, which no one wants to do.
To give an idea on how separate they are, look at ios_base::sync_with_stdio - a dedicated function to make fpritnf and operator<< interoperate.
To make your system work, you probably have to replace fprintf by operator<<. Another way would be adjusting the fprintf's format string, but you would have to add the obscure call to ios_base::sync_with_stdio to your code.
The way to indicate the number of decimals in fprintf is %.[number]f; in your case, for 3 decimals the code will be
fprintf( myFile, "%i\t%.3f\t%.3f\n", k+1, vector[k].x, vector[k].y );

What does the combination of setf(ios::left, ios::adjustfield) do?

I was reading a textbook and I came across this line.
It seems to format output prettily in two columns (I'm guessing the left one get set width making the right one look even since it all starts at the same column). I'm not too sure about what the line is really doing though.
cout.setf(ios::left, ios::adjustfield);
Can someone explain this to me?
It forces text in a fixed width field to be output with left justification. See this reference. This is using the second override of that function that takes in the mask in which to set the particular flags.
This override will clear any existing flags that are set in std::ios_base::adjustfield, which handles justification of text output through a stream object.
The override that doesn't take the flag mask (second parameter) will simply additionally set the flag specified, which doesn't make a lot of sense in the case of adjustfield since the valid values are only left, right, and internal, which all deal with text justification.
Hopefully this small example will make it clear:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout.setf(std::ios::left, std::ios::adjustfield);
cout << setfill('^') << setw(10) << "Hello" << "\n";
cout.setf(std::ios::right, std::ios::adjustfield);
cout << setfill('0') << setw(10) << "99\n";
return 0;
}
It gives the output:
Hello^^^^^
000000099

how to truncate width of integral types with std::ostringstream?

Say you have something like:
std::ostringstream oss;
int value(42);
oss.fill('0');
oss << std::setw(3) << value;
cout << oss.str();
OUTPUT: 042
This output is because std::setw ensures a minimum width and we told the stream to fill with 0 however how do you do the opposite and specify a maximum width so that display will be truncated in STL and native C++ preferably ...
Currently I have something which I consider an ugly and inefficient hack:
std::ostringstream oss;
int value(1239999);
oss.fill('0');
oss << std::setw(3) << boost::lexical_cast<std::string, int>(value).substr(0, 3);
cout << oss.str();
OUTPUT: 123
I've looked at boost::format but it's the same story there as far as I can tell there is no way to do this "prettily" ... any suggestions?
UPDATE: std::ostringstream and STL streams in general are known to perform slowly compared to other containers and template objects of STL. Perhaps I would be better off making a message queue object which wraps and internally uses a std::queue and then just use sprintf_s for formatting purposes?
Truncating to remove significant digits is "frowned upon" by most modern programmers. In the bad old days of FORTRAN formatting, it was pretty common to get output like
Total Sales
-----------
9,314,832.36
1,700,328.04
*,***,***,**
8,314,159.26
...
Even modern day Excel falls into this trap with its field width overflow indication of ########
If the number being output does not fit into the field width, the current philosophy is to break the boundaries of the field width and reliably show the value. The only disadvantage would be if a FORTRAN program is going to read the input (thus expecting strict column usage).
The stream formatting capabilities are not intended as a general purpose string manipulation package. What you are trying to do does not make much sense numerically, so it is not supported - using the substring or similar functions is the way to go. You can (and should, if you need this in more than one place) write your own function to do the job.
Something like:
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
void First3( std::ostream & os, int value ) {
std::ostringstream oss;
oss.fill('0');
oss << std::setw(3) << value;
os << oss.str().substr( 0, 3 );
}
int main() {
First3( std::cout, 1239999 );
std::cout << " ";
First3( std::cout, 1 );
}
Note there is no need for Boost to be used.

Parse int to string with stringstream

Well!
I feel really stupid for this question, and I wholly don't mind if I get downvoted for this, but I guess I wouldn't be posting this if I had not at least made an earnest attempt at looking for the solution.
I'm currently working on Euler Problem 4, finding the largest palindromic number of two three-digit numbers [100..999].
As you might guess, I'm at the part where I have to work with the integer I made. I looked up a few sites and saw a few standards for converting an Int to a String, one of which included stringstream.
So my code looked like this:
// tempTotal is my int value I want converted.
void toString( int tempTotal, string &str )
{
ostringstream ss; // C++ Standard compliant method.
ss << tempTotal;
str = ss.str(); // Overwrite referenced value of given string.
}
and the function calling it was:
else
{
toString( tempTotal, store );
cout << loop1 << " x " << loop2 << "= " << store << endl;
}
So far, so good. I can't really see an error in what I've written, but the output gives me the address to something. It stays constant, so I don't really know what the program is doing there.
Secondly, I tried .ToString(), string.valueOf( tempTotal ), (string)tempTotal, or simply store = temptotal.
All refused to work. When I simply tried doing an implicit cast with store = tempTotal, it didn't give me a value at all. When I tried checking output it literally printed nothing. I don't know if anything was copied into my string that simply isn't a printable character, or if the compiler just ignored it. I really don't know.
So even though I feel this is a really, really lame question, I just have to ask:
How do I convert that stupid integer to a string with the stringstream? The other tries are more or less irrelevant for me, I just really want to know why my stringstream solution isn't working.
EDIT:
Wow. Seriously. This is kind of embarrassing. I forgot to set my tempTotal variable to something. It was uninitialized, so therefore I couldn't copy anything and the reason the program gave me either a 0 or nothing at all.
Hope people can have a laugh though, so I think this question would now be better suited for deletion since it doesn't really serve a purpose unless xD But thanks to everybody who tried to help me!
Have you tried just outputting the integer as is? If you're only converting it to a string to output it, then don't bother since cout will do that for you.
else
{
// toString( tempTotal, store ); // Skip this step.
cout << loop1 << " x " << loop2 << "= " << tempTotal << endl;
}
I have a feeling that it's likely that tempTotal doesn't have the value you think it has.
I know this doesn't directly answer your question but you don't need to write your own conversion function, you can use boost
#include <boost/lexical_cast.hpp>
using boost::lexical_cast;
//usage example
std::string s = lexical_cast<std::string>(tempTotal);
Try the following:
string toString(int tempTotal)
{
ostringstream ss;
ss << tempTotal;
return ss.str();
}
string store = toString(tempTotal);
If you want to output the integer, you don't even need to convert it; just insert it into the standard output:
int i = 100;
cout << i;
If you want the string representation, you're doing good. Insert it into a stringstream as you did, and ask for it's str().
If that doesn't work, I suggest you minimize the amount of code, and try to pinpoint the actual problem using a debugger :)
Short answer: your method to convert an int to a string works. Got any other questions?