[RFC] A stream buffer for wcin
Pétur Runólfsson
peturr02@ru.is
Sun Feb 16 17:52:00 GMT 2003
Hi,
It is currently possible to mix use of cin with use of stdin. Should
this also apply to wcin? That is, should the following work?
wint_t c = wcin.rdbuf()->sgetc();
assert(c == getwchar());
ungetwc(0x20ac, stdin);
assert(wcin.rdbuf()->sgetc() == 0x20ac);
assert(wcin.rdbuf()->sbumpc() == 0x20ac);
getwchar();
wcin.rdbuf()->sputbackc(0x800);
assert(getwchar() == 0x800);
It seems clear that if this is supposed to work, then
* wcin calls should succeed if fwide(stdin, 0) > 0, and should not
set fwide(stdin, -1)
* wcin and stdin need to share a conversion state
I don't see how either of these can hold if wfilebuf is used as the
stream buffer for wcin (at least not without something like libio).
Here is a streambuf that I think gives the expected behaviour for
wcin (at least the above example works)
class wcinbuf : public std::wstreambuf
{
protected:
virtual int_type underflow();
virtual int_type uflow();
virtual std::streamsize xsgetn(char_type* s, std::streamsize n);
virtual int_type pbackfail(int_type c = traits_type::eof());
};
wcinbuf::int_type
wcinbuf::underflow()
{
int_type c = std::getwchar();
if (c == WEOF || std::ungetwc(c, stdin) == WEOF)
return WEOF;
return c;
}
wcinbuf::int_type
wcinbuf::uflow()
{
return getwchar();
}
std::streamsize
wcinbuf::xsgetn(char_type* s, std::streamsize n)
{
std::streamsize ret = 0;
for (; ret < n; ++ret)
{
int_type c = getwchar();
if (c == WEOF)
break;
s[ret] = traits_type::to_char_type(c);
}
return ret;
}
wcinbuf::int_type
wcinbuf::pbackfail(int_type c)
{
if (c == WEOF)
return WEOF;
return ungetwc(c, stdin);
}
Does this make sense?
Is anybody else working on wcin?
If nobody objects, I'll send in a patch soon.
Regards,
Petur
More information about the Libstdc++
mailing list