From: piwi on
On Jan 11, 11:03 pm, Walter van der Hee <him...(a)hotmail.com> wrote:
>
> The codecvt facet is only used when you use a filestream, the overflow
> method on the filebuf calls the out method on the facet.
> If you want to make your facet working with other streams as well, you
> need to write a 'filtering streambuf' and call your facet from there.
>

Is there any rationale to that (using translation between characters
encoding only for filestream)?

Thanks,

--
Bruno


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: DeMarcus on
piwi wrote:
> On Jan 12, 1:16 am, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote:
>> This may be what you are looking for. Put it in the beginning of main.
>>
>> std::ios::sync_with_stdio( false );
>
> This indeed solves my problem! But I don't really understand what it
> does.
> On the cplusplus.com page: http://www.cplusplus.com/reference/iostream/ios_base/sync_with_stdio/
>
> It says that it "Toggles on or off synchronization of the iostream
> standard streams with the standard C streams."
>
> Do you have any explanation of why turning synch off does use the
> facet?
>

No, I have no idea. Or rather the opposite, I don't know why sync on
does not use the facet.

In The Standard C++ Library by Josuttis one can read the following.

"Depending on the implementation, this synchronization might imply some
often unnecessary overhead. For example, if the standard C++ streams are
implemented using the standard C file, this basically inhibits buffering
in the corresponding stream buffers. However, the buffer in the stream
buffers is necessary for some optimizations especially during formatted
reading (see Section 13.14.2, page 682). To allow switching to a better
implementation, the static member function sync_with_stdio() is defined
for the class ios_base (Table 13.46)"




--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Walter van der Hee on
On 12 Jan, 19:38, piwi <bruno.lemarch...(a)gmail.com> wrote:
> On Jan 11, 11:03 pm, Walter van der Hee <him...(a)hotmail.com> wrote:
>
>
>
> > The codecvt facet is only used when you use a filestream, the overflow
> > method on the filebuf calls the out method on the facet.
> > If you want to make your facet working with other streams as well, you
> > need to write a 'filtering streambuf' and call your facet from there.
>
> Is there any rationale to that (using translation between characters
> encoding only for filestream)?

{ edits: signature and quoted banner removed. please remove extraneous quoted
material before posting. -mod }

Not really sure, I wasn't in those meetings :-) I guess the idea was
that only external data (read files) could be in a different encoding.
If you have patience with this, I would wait for the new c++ standard,
which will provide conversion functions. As from my experience,
writing your own facets and buffers is quite tricky.

Walter.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Larry Evans on
On 01/08/10 19:26, piwi wrote:
> Hello,
>
> I'm looking for implementing a way to indent some data fed to an
> std::ostream. I found this link:
>
> http://stackoverflow.com/questions/1391746/how-to-easily-indent-output-to-ofstream
>

However, I see that code does use reinterpret_cast:

int& state(state_type& s) const
{return *reinterpret_cast<int*>(&s);}

Maybe that's OK, but maybe not.
[snip]

> Anyway, the code compiles, but does not work all the time. More
> specifically, it indents text when writing into a std::fstream, but
> not when writing in a std::cout ! That's what bothers me. When I put a
> breakpoint in the do_out method, it does not go into it.
[snip]
The code in indent_filtering_ostream.zip here:

http://www.boostpro.com/vault/index.php?&directory=Input%20-%20Output

does work on std::cout. It's not been tested on a std::fstream, but I
don't know any reason why it shouldn't work there.

It does use the boost iostreams library; hence, you'll have to
download
that if you've not done that already. OTOH, since boost/iostreams
was designed to ease doing this sort of thing, using it may avoid
the complexities suggested by the sentence:

As from my experience, writing your own facets and buffers
is quite tricky.

from another post in this thread:

http://groups.google.com/group/comp.lang.c++.moderated/msg/f2797a4ed4320ebd

Good luck!

-Larry


HTH.

-Larry

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: dietmar_kuehl on
On Jan 9, 1:26 am, piwi <bruno.lemarch...(a)gmail.com> wrote:
> I'm looking for implementing a way to indent some data fed to an
> std::ostream. I found this link:
>
> http://stackoverflow.com/questions/1391746/how-to-easily-indent-outpu...
>
> that proposes to use a facet; I think it is a good idea (and having
> the opportunity to work with locales for the first time), so I'm
> starting with the provided code from the above link.

Using a facet for this is nonsense! This is neither what facets are
intended to do nor going to work: in particular the codecvt facets are
not necessarily used in any stream buffer except in filebuf. A much
more sensible (and much easier to implement) approach is to create a
filtering stream buffer which just replaces every newline by a newline
followed by the appropriate number of spaces. In its simplest form
(non-optimized) form it just takes a few lines of code:

struct indentbuf: std::streambuf
{
indentbuf(std::streambuf* sbuf, int indent):
m_sbuf(sbuf), m_indent(indent) {}
private:
int_type overflow(int_type c)
{
if (c != std::char_traits::eof())
{
this->m_sbuf->sputc(c);
if (c == '\n')
{
std::fill_n(std::ostreambuf_iterator<char>(this->m_sbuf),
this->m_indent, ' ');
}
}
return std::char_traits::not_eof(c);
}
int sync() { return this->m_sbuf->pubsync(); }
std::streambuf* m_sbuf;
int m_indent;
};

You'd create a new std::ostream with using something like this:

indentbuf sbuf(std::cout.rdbuf(), 2);
std::ostream indentstream(&sbuf);

Obviously, if you want to use indentation with an existing stream you
can replace that stream's stream buffer with an indentbuf as long as
objects get the proper live time. To round things up would probably
create a stream wrapper which takes another stream buffer and directly
initializes things. Also, it may be sensible to set up a buffer in
stream buffer and do the indentation only upon flushing or when the
buffer gets full: this would improve preformance quite dramatically.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]