|
-
August 17th, 2010, 12:10 AM
#16
Re: Turkish character problem,wstring
Ah, yes - MinGW (gcc on Windows) does not support "_O_U16TEXT" with std::wcout. Only the Microsoft C++ standard library supports that trick.
The problem is that you have to use WriteConsoleW() in order to get Unicode output on the console. So to make it work for any standard C++ Windows compiler we have to do it ourself.
Code:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <locale>
#include <string>
#include <windows.h>
//------------------------------------------------------------------------------
class wconbuf : public std::wstreambuf
{
public:
typedef wchar_t char_type;
typedef std::char_traits<char_type> traits_type;
typedef traits_type::int_type int_type;
typedef traits_type::pos_type pos_type;
typedef traits_type::off_type off_type;
private:
char_type *m_buffer;
enum {BUFFER_SIZE = 4096 / sizeof(char_type)};
public:
wconbuf() : m_buffer(new char_type[BUFFER_SIZE])
{
setp(m_buffer, m_buffer + BUFFER_SIZE);
}//constructor
~wconbuf()
{
pubsync();
delete[] m_buffer;
}//destructor
protected:
virtual int_type overflow(int_type c = traits_type::eof())
{
// send our buffer through WriteConsoleW() if we can get a handle
HANDLE hout = ::GetStdHandle(STD_OUTPUT_HANDLE);
if (hout && (hout != INVALID_HANDLE_VALUE))
{
std::streamsize n = static_cast<std::streamsize>(pptr() - pbase());
DWORD written;
::WriteConsoleW(hout, pbase(), static_cast<DWORD>(n), &written, 0);
}//if
// reset our buffer
setp(m_buffer, m_buffer + BUFFER_SIZE);
// write the passed character if necessary (into our buffer)
if (!traits_type::eq_int_type(c, traits_type::eof()))
{
traits_type::assign(*pptr(), traits_type::to_char_type(c));
pbump(1);
}//if
return traits_type::not_eof(c);
}//overflow
virtual int sync()
{
// flush our buffer
int_type c = overflow(traits_type::eof());
// checking return for eof.
if (traits_type::eq_int_type(c, traits_type::eof()))
return -1;
return 0;
}//sync
};//wconbuf
//------------------------------------------------------------------------------
template <class charT, class traits = std::char_traits<charT> >
struct scoped_basic_streambuf_assignment
{
typedef std::basic_ios<charT, traits> stream_type;
typedef std::basic_streambuf<charT, traits> streambuf_type;
stream_type &m_s;
streambuf_type *m_orig_sb;
scoped_basic_streambuf_assignment(stream_type &s, streambuf_type *new_sb)
: m_s(s)
{
m_orig_sb = m_s.rdbuf(new_sb);
}//constructor
~scoped_basic_streambuf_assignment()
{
m_s.rdbuf(m_orig_sb);
}//destructor
};//scoped_streambuf_assignment
typedef scoped_basic_streambuf_assignment<char> scoped_streambuf_assignment;
typedef scoped_basic_streambuf_assignment<wchar_t> scoped_wstreambuf_assignment;
//------------------------------------------------------------------------------
int main()
{
std::locale::global(std::locale(""));
wconbuf wcon;
scoped_wstreambuf_assignment swsba(std::wcout, &wcon);
const wchar_t *turkish_chars =
L"\u00e7\u00c7\u011f\u011e\u0131\u0130"
L"\u00f6\u00d6\u015f\u015e\u00fc\u00dc";
std::wcout << turkish_chars << std::endl;
// do it again with just the Win32 API
DWORD written;
::WriteConsoleW(::GetStdHandle(STD_OUTPUT_HANDLE),
turkish_chars,
lstrlenW(turkish_chars),
&written, 0);
std::wcout << std::endl;
return 0;
}//main
wconbuf is a custom wide-stream buffer that pumps everything through WriteConsoleW().
gg
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|