The os.pword(index) method is supposed to return current date format specified by a custom manipulator. The result of pword() gets, however, modified by a different stream by it's str(string) method.
ostringstream os;
istringstream is;
CDate f ( 2000, 5, 12 );
os << date_format ( "%Y-%m-%d" ) << f;
is.clear ();
is.str ( "05.06.2003" ); // causes pword() to return "05.06.2003" instead of "%Y-%m-%d"
os.str ("");
os << f;
Class methods:
struct date_format
{
static const int index;
string format;
explicit date_format(const char * fmt)
{
format = string(fmt);
}
friend ostream & operator<<(ostream & s, const date_format & df)
{
s.pword(index) = (void*)df.format.c_str();
return s;
}
};
const int date_format::index = ios_base::xalloc();
class CDate
{
...
friend ostream & operator<<(ostream & os, const CDate & cdate)
{
/* should point to the current date format of os */
const char * ptr = (const char*)os.pword(date_format::index);
...
return os;
}
}
What causes such behaviour and what can be done to avoid it?
You're experiencing undefined behvaior. In your operator<<(ostream & s, const date_format& df) you set s.pword(index) to a pointer to a data member of a temporary date_format instance. Since date_format( "%Y-%m-%d" ) destructs at the end of the expression, your stream is left with a dangling pointer.
Try making a deep copy of the string before you set a pointer to it.
Related
I'm unable to figure out why the output I received isn't just "00110" but has other giberrish characters in it. Not sure what's wrong with my vector push_back.. It definitely makes sense to me. If I changed it to std::string implementation, it would give a correct output. But in this case, I would need to use vector for proper encapsulation of the object's state. I've been debugging for a few hours now, but still can't find out why. Hope anyone is able to help! Thanks! Note: main() can't be modified.
#include <iostream>
#include <vector>
template<size_t NumBits>
class bitsetts
{
private:
static const unsigned int NO_OF_BITS = CHAR_BIT * sizeof(int); //32 bits
static const unsigned NumBytes = (NumBits - 7) /8;
unsigned char array[NumBytes];
public:
bitsetts() { }
void set(size_t bit, bool val = true) {
if (val == true)
{
array[bit] |= (val << bit );
}
else
{
array[bit] &= (val << bit );
}
}
bool test(size_t bit) const {
return array[bit] & (1U << bit );
}
const std::string to_string()
{
std::vector<char> str;
for (unsigned int i=NumBits; i-- > 0;)
str.push_back('0' + test(i));
return str.data();
}
friend std::ostream& operator<<(std::ostream& os, const bitsetts& ob)
{
for (unsigned i = NumBits; i-- > 0;)
os << ob.test(i);
return os << '\n';
}
};
int main()
{
try
{
bitsetts<5> bitsetts;
bitsetts.set(1);
bitsetts.set(2);
const std::string st = bitsetts.to_string();
if (st != "00110")
{
std::cout << st << std::endl;
throw std::runtime_error{ "-" };
}
}
catch (const std::exception& exception)
{
std::cout << "Conversion failed\n";
}
}
You are filling the std::vector with char values and then constructing a std::string from the raw char data using the std::string constructor that takes a single const char* parameter. That constructor expects the char data to be null-terminated, but you are not pushing a null terminator into your vector, which is why you get extra garbage on the end of your std::string.
So, either push a null terminator into the vector, eg:
const std::string to_string()
{
std::vector<char> str;
for (unsigned int i=NumBits; i-- > 0;)
str.push_back('0' + test(i));
str.push_back('\0'); // <-- add this!
return str.data();
}
Or, use a different std::string constructor that can take the vector's size() as a parameter, eg:
const std::string to_string()
{
std::vector<char> str;
for (unsigned int i=NumBits; i-- > 0;)
str.push_back('0' + test(i));
return std::string(str.data(), str.size()); // <-- add size()!
}
On a side note: your to_string() method should be marked as const, eg:
const std::string to_string() const
Which would then allow you to use to_string() inside of your operator<<, eg:
friend std::ostream& operator<<(std::ostream& os, const bitsetts& b)
{
return os << b.to_string() << '\n';
}
How do I do the following with std::cout?
double my_double = 42.0;
char str[12];
printf_s("%11.6lf", my_double); // Prints " 42.000000"
I am just about ready to give up and use sprintf_s.
More generally, where can I find a reference on std::ostream formatting that lists everything in one place, rather than spreading it all out in a long tutorial?
EDIT Dec 21, 2017 - See my answer below. It uses features that were not available when I asked this question in 2012.
std::cout << std::fixed << std::setw(11) << std::setprecision(6) << my_double;
You need to add
#include <iomanip>
You need stream manipulators
You may "fill" the empty places with whatever char you want. Like this:
std::cout << std::fixed << std::setw(11) << std::setprecision(6)
<< std::setfill('0') << my_double;
std::cout << boost::format("%11.6f") % my_double;
You have to #include <boost\format.hpp>
In C++20 you can to do
double my_double = 42.0;
char str[12];
std::format_to_n(str, sizeof(str), "{:11.6}", my_double);
or
std::string s = std::format("{:11.6}", my_double);
In pre-C++20 you can use the {fmt} library that provides an implementation of format_to_n.
Disclaimer: I'm the author of {fmt} and C++20 std::format.
In general, you want to avoid specifying things like 11 and 6 at the
point of output. That's physical markup, and you want logical markup;
e.g. pressure, or volume. That way, you define in a single place
how pressure or volume are formatted, and if that formatting changes,
you don't have to search through out the program to find where to change
the format (and accidentally change the format of something else). In
C++, you do this by defining a manipulator, which sets the various
formatting options, and preferrably restores them at the end of the full
expression. So you end up writing things like:
std::cout << pressure << my_double;
Although I definitly wouldn't use it in production code, I've found the
following FFmt formatter useful for quicky jobs:
class FFmt : public StateSavingManip
{
public:
explicit FFmt(
int width,
int prec = 6,
std::ios::fmtflags additionalFlags
= static_cast<std::ios::fmtflags>(),
char fill = ' ' );
protected:
virtual void setState( std::ios& targetStream ) const;
private:
int myWidth;
int myPrec;
std::ios::fmtflags myFlags;
char myFill;
};
FFmt::FFmt(
int width,
int prec,
std::ios::fmtflags additionalFlags,
char fill )
: myWidth( width )
, myPrec( prec )
, myFlags( additionalFlags )
, myFill( fill )
{
myFlags &= ~ std::ios::floatfield
myFlags |= std::ios::fixed
if ( isdigit( static_cast< unsigned char >( fill ) )
&& (myFlags & std::ios::adjustfield) == 0 ) {
myFlags |= std::ios::internal
}
}
void
FFmt::setState(
std::ios& targetStream ) const
{
targetStream.flags( myFlags )
targetStream.width( myWidth )
targetStream.precision( myPrec )
targetStream.fill( myFill )
}
This allows writing things like:
std::cout << FFmt( 11, 6 ) << my_double;
And for the record:
class StateSavingManip
{
public:
StateSavingManip(
StateSavingManip const& other );
virtual ~StateSavingManip();
void operator()( std::ios& stream ) const;
protected:
StateSavingManip();
private:
virtual void setState( std::ios& stream ) const = 0;
private:
StateSavingManip& operator=( StateSavingManip const& );
private:
mutable std::ios* myStream;
mutable std::ios::fmtflags
mySavedFlags;
mutable int mySavedPrec;
mutable char mySavedFill;
};
inline std::ostream&
operator<<(
std::ostream& out,
StateSavingManip const&
manip )
{
manip( out );
return out;
}
inline std::istream&
operator>>(
std::istream& in,
StateSavingManip const&
manip )
{
manip( in );
return in;
}
StateSavingManip.cc:
namespace {
// We maintain the value returned by ios::xalloc() + 1, and not
// the value itself. The actual value may be zero, and we need
// to be able to distinguish it from the 0 resulting from 0
// initialization. The function getXAlloc() returns this value
// -1, so we add one in the initialization.
int getXAlloc();
int ourXAlloc = getXAlloc() + 1;
int
getXAlloc()
{
if ( ourXAlloc == 0 ) {
ourXAlloc = std::ios::xalloc() + 1;
assert( ourXAlloc != 0 );
}
return ourXAlloc - 1;
}
}
StateSavingManip::StateSavingManip()
: myStream( NULL )
{
}
StateSavingManip::StateSavingManip(
StateSavingManip const&
other )
{
assert( other.myStream == NULL );
}
StateSavingManip::~StateSavingManip()
{
if ( myStream != NULL ) {
myStream->flags( mySavedFlags );
myStream->precision( mySavedPrec );
myStream->fill( mySavedFill );
myStream->pword( getXAlloc() ) = NULL;
}
}
void
StateSavingManip::operator()(
std::ios& stream ) const
{
void*& backptr = stream.pword( getXAlloc() );
if ( backptr == NULL ) {
backptr = const_cast< StateSavingManip* >( this );
myStream = &stream;
mySavedFlags = stream.flags();
mySavedPrec = stream.precision();
mySavedFill = stream.fill();
}
setState( stream );
}
#include <iostream>
#include <iomanip>
int main() {
double my_double = 42.0;
std::cout << std::fixed << std::setw(11)
<< std::setprecision(6) << my_double << std::endl;
return 0;
}
For future visitors who prefer actual printf-style format specs with std::ostream, here is yet another variation, based on Martin York's excellent post in another SO question: https://stackoverflow.com/a/535636:
#include <iostream>
#include <iomanip>
#include <stdio.h> //snprintf
class FMT
{
public:
explicit FMT(const char* fmt): m_fmt(fmt) {}
private:
class fmter //actual worker class
{
public:
explicit fmter(std::ostream& strm, const FMT& fmt): m_strm(strm), m_fmt(fmt.m_fmt) {}
//output next object (any type) to stream:
template<typename TYPE>
std::ostream& operator<<(const TYPE& value)
{
// return m_strm << "FMT(" << m_fmt << "," << value << ")";
char buf[40]; //enlarge as needed
snprintf(buf, sizeof(buf), m_fmt, value);
return m_strm << buf;
}
private:
std::ostream& m_strm;
const char* m_fmt;
};
const char* m_fmt; //save fmt string for inner class
//kludge: return derived stream to allow operator overloading:
friend FMT::fmter operator<<(std::ostream& strm, const FMT& fmt)
{
return FMT::fmter(strm, fmt);
}
};
usage example:
double my_double = 42.0;
cout << FMT("%11.6f") << my_double << "more stuff\n";
or even:
int val = 42;
cout << val << " in hex is " << FMT(" 0x%x") << val << "\n";
it's me, the OP, Jive Dadson - five years on. C++17 is becoming a reality.
The advent of variadic template parameters with perfect forwarding has made life so much simpler. The chained madness of ostream<< and boost::format% can be dispensed with. The function oprintf below fills the bill. Work in progress. Feel free to chime in on error-handling, etc...
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <string_view>
namespace dj {
template<class Out, class... Args>
Out& oprintf(Out &out, const std::string_view &fmt, Args&&... args) {
const int sz = 512;
char buffer[sz];
int cx = snprintf(buffer, sz, fmt.data(), std::forward<Args>(args)...);
if (cx >= 0 && cx < sz) {
return out.write(buffer, cx);
} else if (cx > 0) {
// Big output
std::string buff2;
buff2.resize(cx + 1);
snprintf(buff2.data(), cx, fmt.data(), std::forward<Args>(args)...);
return out.write(buff2.data(), cx);
} else {
// Throw?
return out;
}
}
}
int main() {
const double my_double = 42.0;
dj::oprintf(std::cout, "%s %11.6lf\n", "My double ", my_double);
return 0;
}
Some great answers already; kudos to those!
This is based on some of them. I have added type assertions for POD types, since they are the only safe types usable with printf().
#include <iostream>
#include <stdio.h>
#include <type_traits>
namespace fmt {
namespace detail {
template<typename T>
struct printf_impl
{
const char* fmt;
const T v;
printf_impl(const char* fmt, const T& v) : fmt(fmt), v(v) {}
};
template<typename T>
inline typename std::enable_if<std::is_pod<T>::value, std::ostream& >::type
operator<<(std::ostream& os, const printf_impl<T>& p)
{
char buf[40];
::snprintf(buf, sizeof(buf), p.fmt, p.v, 40);
return os << buf;
}
} // namespace detail
template<typename T>
inline typename std::enable_if<std::is_pod<T>::value, detail::printf_impl<T> >::type
printf(const char* fmt, const T& v)
{
return detail::printf_impl<T>(fmt, v);
}
} // namespace fmt
Example usage it as below.
std::cout << fmt::printf("%11.6f", my_double);
Give it a try on Coliru.
I have few functions with switches dealing with ostreams to specify exact template type for object to print.
BUT somehow when i'm using nested functions extra address appears in output stream.
Code example:
#include <iostream>
using namespace std;
ostream & tmp2( ostream & in )
{
return in << "out";
}
ostream & tmp( ostream & in )
{
return in << tmp2( in );
}
int main(int argc, char** argv)
{
int t = 2;
switch (t)
{
case 2:
std::cout << tmp;
}
return 0;
}
OUTPUT:
"out0x600e08"
any ideas why is that and how to prevent this?
ostream & tmp( ostream & in )
{
return in << tmp2( in );
}
That is equivalent to:
ostream & tmp( ostream & in )
{
tmp2(in);
in << in; // This line causes the extra output.
return in;
}
You probably meant to use:
ostream & tmp( ostream & in )
{
return tmp2( in );
}
I would like to overload operator<< like this:
ostringstream oss;
MyDate a(2000, 1, 2);
oss << dateFormat("%Y/%m/%d") << a;
assert(oss.str() == "2000-01-02");
so that the date at a will be formatted to specific format. How to achieve this?
In order to store custom state in a stream, you need to use the xalloc static function to get a unique index, and then either pword to get a pointer at that index (allocated specifically for each stream it is used on), or iword to get an integer at that index(allocated specifically for each stream it is used on). In your case, you will probably want pword. You can use the pointer returned by pword to point to a dynamically allocated object which stores the formatting information.
struct DateFormatter
{
// The implementation of this class (e.g. parsing the format string)
// is a seperate issue. If you need help with it, you can ask another
// question
static int xalloc_index;
};
int DateFormatter::xalloc_index = std::ios_base::xalloc();
void destroy_date_formatter(std::ios_base::event evt, std::ios_base& io, int idx)
{
if (evt == std::ios_base::erase_event) {
void*& vp = io.pword(DateFormatter::xalloc_index);
delete (DateFormatter*)(vp);
}
}
DateFormatter& get_date_formatter(std::ios_base& io) {
void*& vp = io.pword(DateFormatter::xalloc_index);
if (!vp) {
vp = new DateFormatter;
io.register_callback(destroy_date_formatter, 0);
}
return *static_cast<DateFormatter*>(vp);
}
std::ostream& operator<<(std::ostream& os, const DateFormatter& df) {
get_date_formatter(os) = df;
return os;
}
std::ostream& operator<<(std::ostream& os, const MyDate& date)
{
DateFormatter& df = get_date_formatter(os);
// format output according to df
return os;
}
int main() {
MyDate a ( 2000, 1, 2 );
std::cout << DateFormatter("%Y/%m/%d") << a;
}
This is the standard method. It is terrible, in my opinion. I much prefer an alternative approach, which is to pass the date object together with the formatting as a single object. For example:
class DateFormatter
{
const MyDate* date;
std::string format_string;
DateFormatter(const MyDate& _date, std::string _format_string)
:date(&_date)
,format_string(_format_string)
{}
friend std::ostream& operator<<(std::ostream& os, const DateFormatter& df) {
// handle formatting details here
return os;
}
};
int main() {
MyDate a ( 2000, 1, 2 );
std::cout << DateFormatter(a, "%Y/%m/%d");
}
Or you can do something like that (using static variable):
#include <iostream>
struct MyDate
{
MyDate(int y, int m, int d): year{y}, month{m}, day{d} {}
int year{};
int month{};
int day{};
};
class DateFormatter
{
public:
DateFormatter(const std::string & format)
{
format_ = format;
}
static const std::string & format()
{
return format_;
}
private:
static std::string format_;
};
std::string DateFormatter::format_ = {"Default Format"};
std::ostream & operator<< (std::ostream & stream, const DateFormatter &)
{
return stream;
}
std::ostream & operator<< (std::ostream & stream, const MyDate & date)
{
auto currentFormat = DateFormatter::format();
// some code using current format ...
return stream << currentFormat << " - " << date.year << "/" << date.month << "/" << date.day;
}
int main(void)
{
MyDate date{2016,4,18};
std::cout << date << std::endl;
std::cout << DateFormatter("New format") << date << std::endl;
return 0;
}
I have a family of classes that contain only variables of the following types: std::string, int, double. I should be able to serialize/deserialize objects of these classes to/from C string (null terminated). I don't want to use some 3rdparty serializer and do not want to write full-featured serializer by myself. I will serialize/deserialize only once in my code.
So, how to write very very tiny and yet elegant serializer and do it pretty fast?
UPDATE
I've written and tested my own. Maybe it will be useful for someone. If you notice some bugs or have some suggestions how to make it better, let me know. Here it is:
typedef std::ostringstream ostr;
typedef std::istringstream istr;
const char delimiter = '\n';
const int doublePrecision = 15;
void Save(ostr& os, int x) { os << x << delimiter; }
void Save(ostr& os, double x)
{
os.precision(doublePrecision);
os << x << delimiter;
}
void Save(ostr& os, const std::string& x) { os << x << delimiter; }
void Load(istr& is, int& x)
{
is >> x;
is.rdbuf()->sbumpc(); // get rid of delimiter
}
void Load(istr& is, double& x)
{
is >> x;
is.rdbuf()->sbumpc(); // get rid of delimiter
}
void Load(istr& is, std::string& x) { getline(is, x, delimiter); }
Test:
std::string a = "Test string 1 2 and 2.33";
std::string b = "45";
double c = 45.7;
int d = 58;
double e = 1.0/2048;
std::ostringstream os;
Save(os, a);
Save(os, b);
Save(os, c);
Save(os, d);
Save(os, e);
std::string serialized = os.str();
std::string aa;
std::string bb;
double cc = 0.0;
int dd = 0;
double ee = 0.0;
std::istringstream is(serialized);
Load(is, aa);
Load(is, bb);
Load(is, cc);
Load(is, dd);
Load(is, ee);
ASSERT(a == aa);
ASSERT(b == bb);
ASSERT(c == cc);
ASSERT(d == dd);
ASSERT(e == ee);
There are 2 ways of serializing string data to a stream, you either do it C-style and use a null to terminate it or (more portably and easier to read) first output a byte that says how long the string is then write the string.
Now if you want to differentiate a string from a non-string (number in this case), you can prepend every "packet" (item) with a byte code, say 0x00 for int, 0x01 for double, 0x02 for string, and branch a switch off depending on what the code is. This way you can even write the int/double as a byte, so you won't lose precision and you'll also end up with a smaller/easier to read file.
void save(std::ostringstream& out, const std::string& x)
{
out << x;
}
void read(std::istringstream& in, std::string& x)
{
in.str(x);
}
from here.
I know you don't want to use a 3rdParty serializer, but if you would reconsider: use Boost.Serialization.
(even if this is not the answer for you, it might be for someone else stumbling on this question)
Very simple example
class some_data
{
public:
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & my_string;
ar & my_double;
}
private:
std::string my_string;
double my_double;
};
and then to save:
my_data dataObject;
std::ofstream ofs("filename");
boost::archive::text_oarchive oa(ofs);
oa << dataObject;
or to load:
my_data dataObject;
std::ifstream ifs("filename");
boost::archive::text_iarchive ia(ifs);
ia >> dataObject;
See the sun xdr format. It's binary and efficient.
I have a tiny custom class to do this, as an example:
Marshall& Marshall::enc(const string& str) {
size_t size = str.size();
size_t pad = (4 - (size%4))%4;
size_t size_on_buff = size + pad;
space_for(sizeof(uint32_t) + size + pad);
check_size_t_overflow(size);
enc(static_cast<uint32_t>(size));
// xdr mandates padding
//space_for(size_on_buff);
memcpy(&(*buff)[pos],str.data(), size);
memset(&(*buff)[pos+size],0,pad);
pos+=size_on_buff;
return *this;
}
Marshall& Marshall::dec(string& str) {
str.clear();
size_t size;
dec(size);
size_t pad = (4 - (size%4))%4;
size_t size_on_buff = size + pad;
ck_space_avl(size + pad);
//str.resize(size);
str.assign((char*)&(*buff)[pos],size);
pos+=size_on_buff;
return *this;
}