I'm trying to make my program work with unicode characters.
I'm using Visual Studio 2010 on a Windows 7 x32 machine.
What I want to print is the queen symbol ("\ul2655") and it just doesn't work. I've set my solution to use unicode.
This is my sample code:
#include <iostream>
using namespace std;
int main()
{
SetConsoleOutputCP(CP_UTF8);
wcout << L"\u2655";
return 0;
}
Also, I've tried many other suggestions, but nothing worked. (eg. change the cmd font, apply chcp 65001, which is the same as SetConsoleOutputCP(CP_UTF8), etc).
What is the problem? It's for the first time I encounter such a situation. On linux, it's different.
Thank you.
Once I managed to print chess pieces on the console; there are several complexities involved here.
First of all, you have to enable UTF-16 mode on stdout; this is described here as well as here, and it's exactly as Mehrdad explained.
#include <io.h>
#include <fcntl.h>
...
_setmode(_fileno(stdout), _O_U16TEXT);
Then, even if the output reached the console correctly, on the console you may get garbage instead of the intended characters; this comes form the fact that, at least on my machine (Windows 7), the default console font doesn't support the chess pieces glyphs.
To fix this, you have to choose a different TrueType font which supports them, but to make such a font available you have to go through some hoops; personally, I found out that DejaVu Sans Mono works just fine.
So, at this point, your code should work, and code like this (the example I wrote in the past to test this issue):
#include <wchar.h>
#include <stdio.h>
#include <locale.h>
#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
#endif
enum ChessPiecesT
{
King,
Queen,
Rock,
Bishop,
Knight,
Pawn,
};
enum PlayerT
{
White=0x2654, /* white king */
Black=0x265a, /* black king */
};
/* Provides the character for the piece */
wchar_t PieceChar(enum PlayerT Player, enum ChessPiecesT Piece)
{
return (wchar_t)(Player + Piece);
}
/* First row of the chessboard (black) */
enum ChessPiecesT TopRow[]={Rock, Knight, Bishop, Queen, King, Bishop, Knight, Rock};
void PrintTopRow(enum PlayerT Player)
{
int i;
for(i=0; i<8; i++)
putwchar(PieceChar(Player, TopRow[Player==Black?i: (7-i)]));
putwchar(L'\n');
}
/* Prints the eight pawns */
void PrintPawns(enum PlayerT Player)
{
wchar_t pawnChar=PieceChar(Player, Pawn);
int i;
for(i=0; i<8; i++)
putwchar(pawnChar);
putwchar(L'\n');
}
int main()
{
#ifdef _WIN32
_setmode(_fileno(stdout), _O_U16TEXT);
#else
setlocale(LC_CTYPE, "");
#endif
PrintTopRow(Black);
PrintPawns(Black);
fputws(L"\n\n\n\n", stdout);
PrintPawns(White);
PrintTopRow(White);
return 0;
}
should work equally well on Windows and Linux.
Now you still have a problem: the glyphs will be too small to be meaningful in any way:
this can be solved only by enlarging the console font, but you'd get all the other characters to be way too big to be usable. Thus, all in all, probably the best fix is just to write a GUI application.
Try this instead
_setmode(_fileno(stdout), _O_U16TEXT);
Related
I'm trying to write an ncurses program in c++ that uses color, except every time I compile it acts like my terminal does not support colors, rejecting me when I include a color check, and not printing in color when not checking colors. My terminal does support colors (the terminal itself is terminator term emulator w/ zsh, have tried on xterm and tty). Is there some option I need to add to g++ to tell it to compile with color support? I don't get any errors during compilation or runtime.
Here's my code if it helps:
#include <stdio.h>
#include <ncurses.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
if(!has_colors()) {
printf("Terminal does not support colors \n");
return 0;
}
initscr();
start_color();
init_pair(1, COLOR_BLACK, COLOR_RED);
/* Get terminal dimensions */
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
/* Make X and Y variables global for later */
extern int x;
extern int y;
/* Print test text */
attron(COLOR_PAIR(1));
printw(" This text should be black on red ");
attroff(COLOR_PAIR(1));
refresh();
getch();
return 0;
}
The compiled program just spits out "terminal does not support colors" even though it does. Excluding the check still doesn't work, just spits it out in monochrome.
And before you ask, yes I googled it, and no it didn't help.
i m trying to read and write Farsi characters in c++ and i want to show them in CMD
first thing i fix is Font i add Farsi Character to that and now i can write on the screen for example ب (uni : $0628) with this code:
#include <iostream>
#include <io.h>
#include <fcntl.h>
using namespace std;
int main() {
_setmode(_fileno(stdout), _O_U16TEXT);
wcout << L"\u0628 \n";
wcout << L"ب"<<endl;
system("pause");
}
but how i can keep this character ... for Latin characters we can use char or string but how about Farsi character utf8 ?!
and how i can get them ... for Latin characters we use cin>>or gets_s
should i use wchar_t? if yes how?
because with this code it show wrong character ...
wchar_t a='\u0628';
wcout <<a;
and i can't show this character بـ (uni $FE91) even though that exist in my installed font but ب (uni $0628) showed correctly
thanks in advance
The solution is the following line:
wchar_t a=L'\u0628';
The use of L tells the compiler that your type char is a wide char ("large" type, I guess? At least that's how I remember it) and this makes sure the value doesn't get truncated to 8 bits - thus this works as intended.
UPDATE
If you are building/running this as a console application in Windows you need to manage your code pages accordingly. The following code worked for me when using Cyrillic input (Windows code page 1251) when I set the proper code page before wcin and cout calls, basically at the very top of my main():
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
For Farsi I'd expect you should use code page 1256.
Full test code for your reference:
#include <iostream>
#include <Windows.h>
using namespace std;
void main()
{
SetConsoleOutputCP(1256); // to manage console output
SetConsoleCP(1256); // to properly process console input
wchar_t b;
wcin >> b;
wcout << b << endl;
}
Unlike English and Latin languages, Hebrew - in it's awesomeness, is written right to left. I wan't to get this message across to the computer realm.
I understand I have to use unicode/wchar for the actual string.
I understand I have to set the console to support unicode/wchar.
I understand I have to tell the console to use a supported font.
So I run this code:
#include "stdafx.h" // MS Visual Studio precompiled header file
#include <fcntl.h> // for _setmode
#include <io.h> // for _setmode
#include <windows.h> // for SetCurrentConsoleFontEx
int main()
{
// use unicode/wchar as the actual string.
wchar_t *hebrewString = L"עברית";
// set the console to support unicode/wchar.
_setmode(_fileno(stdout), _O_U16TEXT);
// tell the console to use a supported font.
CONSOLE_FONT_INFOEX info = { 0 };
info.cbSize = sizeof(info);
info.dwFontSize.Y = 20;
wcscpy_s(info.FaceName, L"Courier New");
SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), NULL, &info);
// print
wprintf(L"%s", hebrewString);
// wait for input, so that console won't disappear immediately
getchar();
// return
return 0;
}
This isn't bad, but the actual print is in reverse:
Is there a way to properly configure it so that it will print in the right order, or do I have to manually flip the string before passing it to the console?
I am working on a simple plugin for a game emulator in C++.
The purpose of the plugin is to detect if message posted by user contains more than 3 spaces or message with these strings: : or ;
The code looks like this so far:
#include "common/hercules.h"
#include "common/memmgr.h"
#include "common/mmo.h"
#include "common/socket.h"
#include "common/strlib.h"
#include "map/clif.h"
#include "map/pc.h"
#include "plugins/HPMHooking.h"
#include "common/HPMDataCheck.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
HPExport struct hplugin_info pinfo = {
"GM Impersonate", // Plugin name
SERVER_TYPE_MAP, // Which server types this plugin works with?
"1.0", // Plugin version
HPM_VERSION, // HPM Version (don't change, macro is automatically updated)
};
bool my_pc_process_chat_message(bool retVal___, struct map_session_data *sd, const char *message) {
if (retVal___ == true) {
if (stristr(message, " ")) {
clif->messagecolor_self(sd->fd, COLOR_RED, "Possible GM Impersonation Detected - you cannot use more than 3 spaces in chat.");
return false;
}
if (stristr(message, " : ") || stristr(message, " ; ")) {
clif->messagecolor_self(sd->fd, COLOR_RED, "Possible GM Impersonation Detected - you cannot use : or ; in chat.");
return false;
}
}
return true;
}
HPExport void plugin_init(void) {
addHookPost(pc, process_chat_message, my_pc_process_chat_message);
}
I am not a C++ programmer, I used a sample plugin to work this code out, which appears to be working miraculously. I am now trying to improve this little plugin to detect invisible glyphs, as if they were spaces, in the message char array.
How can I achieve this?
I found this post - https://stackoverflow.com/a/15813530/2332336 but this appears to be for string, not char array. Any ideas?
I'm not sure the solution you linked to is the same as "invisible/Non-ASCII" as it seems only to deal with stripping out 8-bit ASCII codes. However if you want to try the solution you linked to, there is no reason to let the difference in char arrays and strings stand in your way. The String class has a constructor that will work to convert for you.
string mystring(message);
Then you can feel free to use the "stripUnicode" method from the linked solution to see if that gets what you were expecting.
I'm relatively new to WinAPI programming in C++. I'm trying to write a program that will obtain the system hostname using GetComputerName(). Ideally, I want the code to be able to work on English and non-English systems. Below is the code that I'm using:
int main()
{
wstring hostname;
wchar_t nbtName[MAX_COMPUTERNAME_LENGTH + 1];
DWORD length = MAX_COMPUTERNAME_LENGTH + 1;
GetComputerName(nbtName, &length);
hostname = nbtName;
wcout << hostname << endl;
return 0;
}
The code works fine on my English Windows 7 system, but the code doesn't seem to display properly on my German Windows 7 system (which uses German characters for the hostname). I thought that wstring and wchar_t could handle these special characters. Here's what's displayed on my German Windows 7 system.
COMPUTER-Í─▄▀
Am I overlooking something stupid? Thanks!
Use _setmode(_fileno(stdout), _O_U16TEXT) to show Unicode in console window:
#include <iostream>
#include <string>
#include <io.h> //for _setmode
#include <fcntl.h> //for _O_U16TEXT
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
std::wcout << L"ελληνικά\n";
return 0;
}
Or use MessageBoxW(0, hostname.c_str(), 0, 0) or OutputDebugStringW to see Unicode text displayed correctly:
this function has two versions GetComputerNameW for unicode and GetComputerNameA for ANSI. if UNICODE is defined in your environment the the first one will be called. So either make sure UNICODE is defined or try to call the GetComputerNameW directly.
Windows Console output was the culprit. The Unicode characters display correctly in other non-console output. Thanks everyone!