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
Re: Turkish character problem,wstring
Thanks for your answer.
Could you write a simple full application which uses Turkish characters?I didn't understand what should I write after writing your last code.
Re: Turkish character problem,wstring
>> Could you write a simple full application which uses Turkish characters?
The code in post #16 is as simple as it gets under MinGW.
The code in post #12 is as simple as it gets under VC++
If there is something you don't understand, ask a specific question.
gg
Re: Turkish character problem,wstring
Although I couldn't understand what wconbuf does,just using writeconsoleW() which you mentioned worked for Turkish output.Thanks
What should I write after writing wconbuf code,what is it for?
Re: Turkish character problem,wstring
std::wcout << turkish_chars << std::endl;
The only reason that works is because std::wcout's stream buffer has been replaced by an instance of 'wconbuf' - which sends everything through WriteConsoleW.
I first learned all about C++ streams from a book - http://www.angelikalanger.com/iostreams.html
There is some online material as well:
http://gcc.gnu.org/onlinedocs/libstd...treambufs.html
http://stdcxx.apache.org/doc/stdlibug/39-2.html
gg
Re: Turkish character problem,wstring