Indeed, console was not made for this purpose.
If someone comes up with a solution on this matter, please share with us. Especially you Elysa, since you've done it before. As you know, most recent videogames have support for those characters and surely they had to do some code, most fps shooters I know use C programming language like the unreal games, Counter-strike and those. But how did they do it?
Well, I know that the Unreal series made new fonts for this purpose, so can't we do just that? Is it possible then to change the command prompts font to that font in the program it is needed in, but in normal cmd's it would be the standard font?
Thanks!
Firstly, they probably use C++ instead of C, since C is not really a good language for games.
And secondly, they don't write characters to the console. The console is really unfit for things like this.
Writing to the screen using some rendering API is much easier and powerful than the console. Heck, if I wanted, I could even use unicode text on a label on a window without problems.
C or C++ is not the issue here - but we are in the C++ forum, so I guess that's what we should be talking about - but really, both languages support "unicode" and "large sets of characters". The Windows console, however, does not. It has a set of 256 characters that it can display at any given time. You may be able to change which 256 characters those are by changing the "Codepage". For example, codepage 861 is icelandic:
http://www.tachyonsoft.com/cp00861.htm
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
The windows console supports Unicode output via WriteConsoleW(). However, the console has to be using a font with Unicode characters (like Lucida Console).
The easy thing to do on Windows is to use a custom stream buffer that utilizes WriteConsoleW():
If you want to do Unicode file I/O with wfstream, you have to use a custom codecvt facet (that's for another thread).Code:#include <iostream> #include <iomanip> #include <streambuf> #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 into m_sbuf1 and m_sbuf2 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 //------------------------------------------------------------------------------ const wchar_t CHECK_SYM = L'\u221A'; const wchar_t SMALL_LATIN_Ae = L'\u00E6'; const wchar_t SMALL_LATIN_THORN = L'\u00FE'; const wchar_t SMALL_LATIN_O_wACUTE = L'\u00F3'; //------------------------------------------------------------------------------ using namespace std; void display_char(wchar_t c) { wchar_t old_fill = wcout.fill('0'); wcout << L"U+" << uppercase << hex << setw(4) << int(c) << dec << L" = " << c << endl; wcout.fill(old_fill); }//display_char //------------------------------------------------------------------------------ int main() { wconbuf wcon; wcout.rdbuf(&wcon); display_char(CHECK_SYM); display_char(SMALL_LATIN_Ae); display_char(SMALL_LATIN_THORN); display_char(SMALL_LATIN_O_wACUTE); return 0; }//main
gg
Shouldn't wcout be used instead of cout for wide chars?
Last edited by King Mir; 12-04-2008 at 08:24 PM.
It is too clear and so it is hard to see.
A dunce once searched for fire with a lighted lantern.
Had he known what fire was,
He could have cooked his rice much sooner.
>> Shouldn't wcout be used instead of cout for wide chars?
Yes.
>> I believe the deficiency of g++ is the lack of implementation of the wide I/O stream facilities
Correct. The MinGW port of GNU std C++ does not currently support wide streams. However, STLPort does. The previous example I posted works with MinGW + STLPort.
>> You may be able to change which 256 characters those are by changing the "Codepage"
Indeed! I really like those tachyonsoft tables - they let you see what code pages contain a certain glyph and what the character values are in those pages. Take the Latin Small Letter Thorn for example - it has the following character values:
0x95 for CP861
0xE7 for CP850 and CP858
0xFE for CP1252
So this will print the same character 3 times (using Lucida Console):
>> I tried letting it print with the number 254 like you told me about, an it returned a boxCode:SetConsoleOutputCP(861); cout << char(0x95) << endl; SetConsoleOutputCP(850); cout << char(0xE7) << endl; SetConsoleOutputCP(1252); cout << char(0xFE) << endl;
My default console output code page is 437 (DOS USA). If you look up the glyph for 0xFE in that code page, you'll see that it's Unicode character U+25A0, "Black Square". Most of the DOS code pages use 0xFE for the "Black Square" glyph.
gg
The problem is, when I use your code, ahh let me just show you it on a screenshot so you'll understand me ... : http://www.tv.is/vefir/helgi/images/...lp/strange.JPG
So, that box appears instead of þ so, yeah. Can I do anything to get this working? :S
You are not using the Lucida Console font! I just tried it, first with the "default" console font - and I got exactly the same as your result, and then with Lucida Console as the font, and I got three "thorn" characters (or whatever character is called - the one that looks like a b printed on top of a p).
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
So how do I use Lucida console font? Will that get me to print þ? Sorry, I'm a noob.
Right-click on the title bar of your command prompt window, and select properties. Then Select the font tab, and select Lucida Console as your font.
When you click "OK", you can then select to use this "on all consoles" or "just this time". You want to select "all consoles".
--
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
Yeah about that, Codeplug, when I try out your code my compiler Code::Blocks says:
"|13|error: expected class-name before '{' token|" So it seems to have problems after you state first 'public:' line.
Any ideas what is wrong here?
It might depend on the compiler you are using. If it is MinGW then it might not support wide streams. (Code::Blocks is not a compiler but an IDE, and can be set up to use various compilers.)
A side question, now that we have managed to display and perhaps input special characters, what does it take to make functions like toupper/tolower work with them?
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.