How to print a double with a comma - c++

In C++ I've got a float/double variable.
When I print this with for example cout the resulting string is period-delimited.
cout << 3.1415 << endl
$> 3.1415
Is there an easy way to force the double to be printed with a comma?
cout << 3.1415 << endl
$> 3,1415

imbue() cout with a locale whose numpunct facet's decimal_point() member function returns a comma.
Obtaining such a locale can be done in several ways. You could use a named locale available on your system (std::locale("fr"), perhaps). Alternatively, you could derive your own numpuct, implement the do_decimal_point() member in it.
Example of the second approach:
template<typename CharT>
class DecimalSeparator : public std::numpunct<CharT>
{
public:
DecimalSeparator(CharT Separator)
: m_Separator(Separator)
{}
protected:
CharT do_decimal_point()const
{
return m_Separator;
}
private:
CharT m_Separator;
};
Used as:
std::cout.imbue(std::locale(std::cout.getloc(), new DecimalSeparator<char>(',')));

This is controlled by your program's locale.
How you set a program's default locale depends on the platform. On POSIX type platforms, it's with the LANG and LC_* environment variables, for instance.
You can force a particular locale -- different from the default -- within a C++ program by calling ios::imbue. Something like this might work:
#include <locale>
cout.imbue(std::locale("German_germany"));
The idea is to force a locale where comma is the decimal separator. You might need to adjust the "German_germany" string to get the behavior you want on your particular platform.

You need to impue the stream with a different locale, one whose num_punct (iirc) facet specifies a comma.
If your platform locale formats with commas, then
cout.imbue(locale(""));
should be sufficient.

To be precise, this is controlled by the std::numpunct<charT>::decimal_point() value. You can imbue() another locale with another decimal_point()

Old thread, but anyway ... One should be aware that using a std::locale makes the string "pretty", complete with correct decimal point, thousands separators and what not, depending on the platform and locale. Most probably, using imbue() will break any parsing of the string after it's formatted. For example:
std::ostringstream s;
std::locale l("fr-fr");
s << "without locale: " << 1234.56L << std::endl;
s.imbue(l);
s << "with fr locale: " << 1234.56L << std::endl;
std::cout << s.str();
Gives the following output:
without locale: 1234.56
with fr locale: 1 234,56
Using strtod() or similar on the second string probably won't work very well ... Also, the space between "1" and "2" in the second output string is a non-breaking one, making the string even prettier :-)

Very old thread, but anyway ... I had the problem to fill a text entry under Gtkmm-3.0 with the outcome of a distance calculation. To make things clearer I add an example, where I have concentrated some wisdoms of several posts I read the last days:
#include <locale>
// next not necessary, added only for clarity
#include <gtkmm-3.0/gtkmm.h>
Gtk::Entry m_Text;
// a distance measured in kilometers
double totalDistance = 35.45678;
std::stringstream str;
// I am using locale of Germany, pay attention to the _
str.imbue(std::locale("de_DE"));
// now we have decimal comma instead of point
str << std::fixed << std::setprecision(4) << std::setw(16) << totalDistance << " km";
// the wished formatting corresponds to "%16.4f km" in printf
m_Text.set_text(str.str());

Related

how to define my own special character in cout

for example :
cout << " hello\n400";
will print:
hello
400
another example:
cout << " hello\r400";
will print:
400ello
there is a option to define my own special character?
i would like to make somthing like:
cout << " hello\d400";
would give:
hello
400
(/d is my special character, and i already got the function to get the stdout cursor one line down(cursorDown()),but i just don't how to define a special character that each time will be writted will call to my cursorDown() function)
As said by others there is no way you can make cout understand user defined characters , however what you could do is
std::cout is an object of type std::ostream which overloads operator<<. You could create an object of the struct which parses your string for your special characters and other user defined characters before printing it to a file or console using ostream similar to any log stream.
Example
or
Instead of calling cout << "something\dsomething"
you can call a method special_cout(std::string); which parses the string for user defined characters and executes the calls.
There is no way to define "new" special characters.
But you can make the stream interpret specific characters to have new meanings (that you can define). You can do this using locals.
Some things to note:
The characters in the string "xyza" is just a simple way of encoding a string. Escaped characters are C++ way of allowing you to represent representing characters that are not visible but are well defined. Have a look at an ASCII table and you will see that all characters in the range 00 -> 31 (decimal) have special meanings (often referred to as control characters).
See Here: http://www.asciitable.com/
You can place any character into a string by using the escape sequence to specify its exact value; i.e. \x0A used in a string puts the "New Line" character in the string.
The more commonly used "control characters" have shorthand versions (defined by the C++ language). '\n' => '\x0A' but you can not add new special shorthand characters as this is just a convenience supply by the language (its like a tradition that most languages support).
But given a character can you give it a special meaning in an IO stream. YES. You need to define a facet for a locale then apply that locale to the stream.
Note: Now there is a problem with applying locals to std::cin/std::out. If the stream has already been used (in any way) applying a local may fail and the OS may do stuff with the stream before you reach main() and thus applying a locale to std::cin/std::cout may fail (but you can do it to file and string streams easily).
So how do we do it.
Lets use "Vertical Tab" as the character we want to change the meaning of. I pick this as there is a shortcut for it \v (so its shorter to type than \x0B) and usually has no meaning for terminals.
Lets define the meaning as new line and indent 3 spaces.
#include <locale>
#include <algorithm>
#include <iostream>
#include <fstream>
class IndentFacet: public std::codecvt<char,char,std::mbstate_t>
{
public:
explicit IndentFacet(size_t ref = 0): std::codecvt<char,char,std::mbstate_t>(ref) {}
typedef std::codecvt_base::result result;
typedef std::codecvt<char,char,std::mbstate_t> parent;
typedef parent::intern_type intern_type;
typedef parent::extern_type extern_type;
typedef parent::state_type state_type;
protected:
virtual result do_out(state_type& tabNeeded,
const intern_type* rStart, const intern_type* rEnd, const intern_type*& rNewStart,
extern_type* wStart, extern_type* wEnd, extern_type*& wNewStart) const
{
result res = std::codecvt_base::ok;
for(;(rStart < rEnd) && (wStart < wEnd);++rStart,++wStart)
{
if (*rStart == '\v')
{
if (wEnd - wStart < 4)
{
// We do not have enough space to convert the '\v`
// So stop converting and a subsequent call should do it.
res = std::codecvt_base::partial;
break;
}
// if we find the special character add a new line and three spaces
wStart[0] = '\n';
wStart[1] = ' ';
wStart[2] = ' ';
wStart[3] = ' ';
// Note we do +1 in the for() loop
wStart += 3;
}
else
{
// Otherwise just copy the character.
*wStart = *rStart;
}
}
// Update the read and write points.
rNewStart = rStart;
wNewStart = wStart;
// return the appropriate result.
return res;
}
// Override so the do_out() virtual function is called.
virtual bool do_always_noconv() const throw()
{
return false; // Sometime we add extra tabs
}
};
Some code that uses the locale.
int main()
{
std::ios::sync_with_stdio(false);
/* Imbue std::cout before it is used */
std::cout.imbue(std::locale(std::locale::classic(), new IndentFacet()));
// Notice the use of '\v' after the first lien
std::cout << "Line 1\vLine 2\nLine 3\n";
/* You must imbue a file stream before it is opened. */
std::ofstream data;
data.imbue(std::locale(std::locale::classic(), new IndentFacet()));
data.open("PLOP");
// Notice the use of '\v' after the first lien
data << "Loki\vUses Locale\nTo do something silly\n";
}
The output:
> ./a.out
Line 1
Line 2
Line 3
> cat PLOP
Loki
Uses Locale
To do something silly
BUT
Now writing all this is not really worth it. If you want a fixed indent like that us a named variable that has those specific characters in it. It makes your code slightly more verbose but does the trick.
#include <string>
#include <iostream>
std::string const newLineWithIndent = "\n ";
int main()
{
std::cout << " hello" << newLineWithIndent << "400";
}

Can you set the qDebug() floating point precision and number format globally?

I want to use qDebug(), qInfo() and so on with a custom default floating point precision and number format.
Is there a way to define this globally?
Imagine this:
double num = 1.2;
qDebug() << "My floating point Number is: " << QString::number(num, 'f', 2);
//Output: My floating point Number is 1.20
Now I would like to avoid QString::number(num, 'f', 2) everytime I write a number and would much rather like to use a standard percision and format.
Formatting of a QDebug stream can be controlled through QTextStream manipulators. Therefore, you must call
qDebug() << fixed << qSetRealNumberPrecision(2);
in the beginning of your program.
Note, however, that the formatting state of qDebug() may change later if some (not so carefully written) code sets required formatting and doesn't restore it to the previous state after completing its job.
EDIT
It turns out that the effect of QTextStream manipulators (at least in combination with qDebug()) is limited to the containing statement and doesn't persist. So, the best you can do is define your replacement of qDebug() as follows:
#define myqDebug() qDebug() << fixed << qSetRealNumberPrecision(2)
and use it instead of qDebug():
double num = 1.2;
myqDebug() << "My floating point Number is: " << num << endl;
Output:
My floating point Number is: 1.20
You can't.
qDebug(), qFatal(), etc... return instances of the class QDebug.
The issue is that the operator QDebug::operator<<(float f) is a non virtual class member function.
You cannot define another without getting the compile error message
operator<< is ambiguous

setLocale for reading float numbers from string

I work on Ubuntu and use an english keyboard.When I want to parse float from string in cpp using "strtof" function it is assuming commas, instead of dots as floating point. As a known solution I tried to use setlocale(LC_NUMERIC, "C") however this only helps within the same function scope where strtof is called. However If I need to add setlocale to every function scope it would take too much time. I tried to do this in main function, unfortunately only fixed the problem in the scope of main.
How to make it globally working?
You can set the global locale:
std::locale::global(std::locale("C"));//default.
Which should affect all functions which rely on the global locale.
Note that cout (and I presume cin and cerr) are imbued with the global locale at the moment they are created. Even if the first line of your code sets the global locale, the streams may have been created earlier, so you must imbue the stream with the new locale.
If you need locale specific behavior elsewhere, but don't want your number formatting messed with by default, boost::locale solved this issue -- you can see this question:What are the tradeoffs between boost::locale and std::locale?
Here's an example of output, but parsing behavior is identical:
auto demo = [](const std::string& label)
{
float f = 1234.567890;
std::cout << label << "\n";
std::cout << "\t streamed: " << f << "\n";
std::cout << "\t to_string: " << std::to_string(f) << "\n";
};
std::locale::global(std::locale("C"));//default.
std::cout.imbue(std::locale()); // imbue cout with the global locale.
demo("c locale");
std::locale::global(std::locale("de_DE"));//default.
std::cout.imbue(std::locale()); // imbue cout with the global locale.
demo("std de locale");
boost::locale::generator gen;
std::locale::global(gen("de_DE.UTF-8"));
std::cout.imbue(std::locale()); // imbue cout with the global locale.
demo("boost de locale");
Which provides the following result:
c locale
streamed: 1234.57
to_string: 1234.567871
std de locale
streamed: 1.234,57
to_string: 1234,567871
boost de locale
streamed: 1234.57
to_string: 1234,567871

Issue when "fixed" stream manipulator is removed

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.

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.