I am trying to print hex values for member[0] and member[1] and integer values for _records in the same text file with the following code:
std::ofstream myoutputfile;
myoutputfile << std::hex << (int)(unsigned char)_member[0] << ' ';
myoutputfile << std::hex << (int)(unsigned char)_member[1] << ' ';
myoutputfile<<_records << std::endl;
But this code prints _records in hex too. I have tried:
myoutputfile<<(int)_records << std::endl;
But still it prints it in hex.
Can anyone help please.
Set the format back to decimal using std::dec
myoutputfile<< std::dec << _records << std::endl;
As you've discovered, the base format specifiers are sticky, so there's no need to specify std::hex each time. Your code could be rewritten as follows to achieve the same effect.
std::ofstream myoutputfile;
myoutputfile << std::hex
<< (int)(unsigned char)_member[0] << ' '
<< (int)(unsigned char)_member[1] << ' '
<< std::dec << _records << std::endl;
You could also have the resetting to previous state done automatically by using Boost IO State Savers.
#include <boost/io/ios_state.hpp>
#include <ios>
#include <iostream>
#include <ostream>
int main()
{
auto hex_printer = [](std::ostream& os, unsigned char byte) {
boost::io::ios_flags_saver ifs(os);
os << std::hex << static_cast<unsigned>(byte) << ' ';
};
hex_printer(std::cout, 'A');
std::cout << 42 << '\n';
}
Live demo
The base that's use for conversion from numbers to text is a state of the output stream rather than a function of the input type. You need to do:
myoutputfile<< std::dec << _records << std::endl;
This changes the state of the output stream to put _records using decimal.
std::hex tells an ostream to print everything in hex from that point on. The equivalent that will return it to decimal is std::dec. Try the following:
std::ofstream myoutputfile;
myoutputfile << std::hex;
myoutputfile << _member[0] << ' ';
myoutputfile << _member[1] << ' ';
myoutputfile << std::dec << _records << std::endl;
Check out http://www.cplusplus.com/reference/ios/hex/ as an additional reference.
you can use fprintf, which prints formatted text:
frintf("%x %x %d\n",_member[0],_member[0],_records);
Hope this helps
Related
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;
}
#include <iostream>
#include <locale>
int main(int argc, char** argv) {
std::wcout.imbue(std::locale("zh_CN.UTF-8"));
std::wcout << wchar_t(0) << L"哈哈" << std::endl;
std::cout << char(0) << "haha" << std::endl;
std::cout << "---------------" << std::endl;
std::wcout.clear();
std::wcout << L"哈哈" << std::endl;
std::cout << "haha" << std::endl;
std::cout << "---------------" << std::endl;
std::wcout << L'\0' << L"哈哈" << std::endl;
std::cout << '\0' << "haha" << std::endl;
std::cout << "---------------" << std::endl;
std::wcout.clear();
std::wcout << L"哈哈" << std::endl;
std::cout << "haha" << std::endl;
return 0;
}
The wchar_t(0) and L'\0' seem to different from char(0) and '\0' and cause the ostream to have bad state.
It took me some time to figure out the missing output is not caused by the locale setting but the wchar_t since my original program has somewhere output a wchar_t(0) or '\0'.
My question is how are they different from the char version? And how to correctly use an empty wchar_t?
Thanks in advance.
The null wide character can be written as wchar_t(0) or L'\0'.
The different behaviour you observe is because cout and wcout are text streams. According to cppreference, you should only use printable characters, \t and \n on a text stream. Sending a null character to the text stream may have unexpected results.
If you want to use cout as a binary stream in Windows there are some hacks you can do , see here for ideas.
I am not sure whether those hacks would work for wcout; but from past experience, the status of wcout support in compilers is dubious and I have found it more reliable to just use stdout and do any required translation using facets or explicit functions etc.
Why is std::setw() considering special chars as two chars ? Is there any easy and stylish way to solve this ?
Eg :
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::left << std::setw(10) << "ok" << "ok" << std::endl;
std::cout << std::left << std::setw(10) << "test.." << "ok again" << std::endl;
std::cout << std::left << std::setw(10) << "®èé" << "fail" << std::endl;
return 0;
}
Ouputs :
ok ok
test.. ok again
®èé fail
Here is the live test : http://ideone.com/q57I0H
They are two characters, check the value of sizeof("®èé")
I am working on a C++ program with a lot of numbers that are type double (values in the millions and billions with just a couple places to the right of the decimal point). I am performing calculations on these numbers and then printing the result to text/CSV files. I noticed that in the text files, all of my numbers appear to be rounded (to six digits). So, a value of 13,169,911 is showing up as 13,169,900 in my output file.
Is this rounding only occuring on the print? In order to get the full number of digits in the variable, do I just need to specify something when I write to a file? I included a sample of my write to file code below:
void PrintPropFinance(vector<PropFinance>& PF, int NumProps, int Iterations, int ForecastLength,
string CurDeal, string ModelRunID, string ScenName, Assumptions& Ass) {
string filename;
ofstream OutFile;
ostringstream s1;
s1 << BASEPATH << "Output/" << CurDeal << "_" << ModelRunID << "_" <<
ScenName << "_PropFinance" << ".csv";
filename = s1.str();
OutFile.open(filename);
// Put in the column headers first
OutFile << "PropID" << ","
<< "Item" << ","
<< "StartDate" << ","
<< "NumOfPeriod" << ","
<< "Result" << ","
<< "Isap" << ","
<< "CurLoanBal" << ","
for (int i=1; i<=NumProps; ++i) {
// Populate the single-vector variables
OutFile << PF[i].PropID << ","
<< PF[i].Item << ","
<< PF[i].StartDate << ","
<< PF[i].NumOfPeriod << ","
<< PF[i].Result << ","
<< PF[i].Isap << ","
<< PF[i].CurLoanBal << ","
<< endl;
}
OutFile.close();
}
// Prop finance class definition
class PropFinance {
public:
string PropID;
int Item;
string StartDate;
int NumOfPeriod;
string Isap;
double CurLoanBal;
}
The problem is likely to do with the way the output stream produces the output for doubles: if 13169911 gets printed in "scientific notation", it would look like 1.31699E7. Excel will read this notation just fine, but would put zeros for the digits it does not "see", making the number look like 13,169,900.
To fix this problem, add fixed manipulator when you output your double to ensure that all digits get printed:
OutFile << PF[i].PropID << ","
<< PF[i].Item << ","
<< PF[i].StartDate << ","
<< PF[i].NumOfPeriod << ","
<< fixed << PF[i].Result << ","
<< PF[i].Isap << ","
<< fixed << PF[i].CurLoanBal << ","
<< endl;
You need to use std::setprecision to increase the precision of the stream. By default an iostream has only 6 digits of precision.
Try this:
OutFile << std::setprecision(std::numeric_limits<long double>::digits10 << PF[i].CurLoanBal;
Bear in mind that this will affect all subsequent operations on the stream. To be honest though, that's probably what you want!
As comparison between std::setprecision and std::fixed, this program:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <limits>
int main()
{
const long double test_value = 13169911.7777777;
std::cout << "default precision (6): " << test_value << '\n'
<< "std::fixed: " << std::fixed << test_value << '\n'
<< "std::precision(10): " << std::defaultfloat << std::setprecision(10) << test_value << '\n'
<< "std::precision(10) & std::fixed: " << std::fixed << std::setprecision(10) << test_value << '\n'
<< "max precision: " << std::defaultfloat << std::setprecision(std::numeric_limits<long double>::digits10) << test_value << '\n'
<< "max precision & std::fixed: " << std::fixed << std::setprecision(std::numeric_limits<long double>::digits10) << test_value << '\n'
;
}
Produces this output:
default precision (6): 1.31699e+007
std::fixed: 13169911.777778
std::precision(10): 13169911.78
std::precision(10) & std::fixed: 13169911.7777777000
max precision: 13169911.7777777
max precision & std::fixed: 13169911.777777700000000
So I think you may want std::setprecision rather than std::fixed. Though I imagine that you'll only have two decimal places anyway so perhaps it doesn't matter.
Read more here: http://en.cppreference.com/w/cpp/io/manip/setprecision
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;
}