0

I'm trying to get the infinity symbol (∞) to print but I keeping getting garbage. I've tried everything mentioned here but nothing is working.

What I'm trying to accomplish is this

modifies strength by 9 ∞

I've tried

printf ("%c", 236);
printf ("%c", 236u);

and I get

modifies strength by 9 ì

I've tried

printf("∞");

and I get

modifies strength by 9 ?

I tried this

if ( paf->duration == -1 ){
    setlocale(LC_ALL, "en_US.UTF-8");
    wprintf(L"%lc\n", 8734);
    ch->printf("∞");

Just to see if I could get wprintf to print it but it completely ignores setlocale and wprintf and still gives me

modifies strength by 9 ?

I tried

if ( paf->duration == -1 ){
    std::cout << "\u221E";
    ch->printf("∞");

But got the this warning and error

Error   C2664   'int _CrtDbgReportW(int,const wchar_t *,int,const wchar_t *,const wchar_t *,...)': cannot convert argument 5 from 'int' to 'const wchar_t *'    testROS1a   C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\malloc.h   164 
Warning C4566   character represented by universal-character-name '\u221E' cannot be represented in the current code page (1252)    testROS1a   C:\_Reign of Shadow\TEST\src\CPP\act_info.cpp   3724    

which I can't make heads or tails of. I've exhausted the scope of my knowledge so does anyone know how to make this happen?

Bishop Minter
  • 107
  • 1
  • 3
  • 11

3 Answers3

1

This does the trick on my machine, windows + code page (1252), not sure how universal this is though. I never really got to work a lot with unicode/localization stuff. And there always seems to be one more gotcha.

#include <iostream>
#include <io.h>
#include <fcntl.h>

const wchar_t infinity_symbol = 0x221E;

int main()
{
    // enable windows console to unicode
    _setmode(_fileno(stdout), _O_U16TEXT);
    std::wcout << infinity_symbol;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
  • This works on all Windows versions after XP, it doesn't care about code page and localization because it's Unicode (UTF16). `L'∞'` should work too, unless the console doesn't have the right font. – Barmak Shemirani Oct 21 '21 at 14:17
  • How do I make this work with printf? It prints to the screen using this method: ch->printf("∞"). How do I make std:wcout<printf? – Bishop Minter Oct 21 '21 at 18:19
1

To use the Windows command prompt with wide strings, change the mode as follows, printf/cout won't work until the mode is switched back. Make sure to flush between mode changes:

#include <iostream>
#include <io.h>
#include <fcntl.h>

using namespace std;

int main()
{
    // To use wprintf/wcout and output any BMP (<= U+FFFF) code point
    int org = _setmode(_fileno(stdout), _O_U16TEXT);
    wcout << L'\u221e' << endl;
    wprintf(L"\u221e\n");

    fflush(stdout);
    _setmode(_fileno(stdout), org); // to switch back to cout/printf and default code page
    cout << "hello, world!" << endl;
    printf("hello, world!\n");
}

Output:

∞
∞
hello, world!
hello, world!

If you use UTF-8 source and your compiler accepts it, you can also change the code page of the terminal to 65001 (UTF-8) and it could work with printf as is:

test.c

#include <stdio.h>

int main() {
    printf("∞\n");
}

Console output:

C:\demo>cl /W4 /utf-8 /nologo test.c
test.c

C:\demo>chcp
Active code page: 437

C:\demo>test          ## NOTE: Wrong code page prints mojibake.
∞                   ##       These are UTF-8 bytes interpreted incorrectly.

C:\demo>chcp 65001
Active code page: 65001

C:\demo>test
∞
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • but the output is displayed using "ch->printf". this is no "ch->wprintf" – Bishop Minter Oct 21 '21 at 20:43
  • @Bishop What *is* `ch->printf`? That isn't standard and your example doesn't define it. But if it calls standard `printf` internally you are stuck with no infinity symbol support unless the default code page supports it. – Mark Tolonen Oct 21 '21 at 20:51
  • @BishopMinter For example if you use UTF-8 source and your compiler supports it, you could change the code page of the console to `chcp 65001` (UTF-8) and it *might* output what you want. That Windows code page has known bugs and you also need a console font that supports the symbol. The Microsoft compiler has a `/utf-8` compiler switch. I'll add an example: – Mark Tolonen Oct 21 '21 at 21:09
  • Are you using gcc or Visual Studio? `printf("∞\n")` has issues in VS. But the `_setmode` method is reliable. – Barmak Shemirani Oct 21 '21 at 23:22
  • @BarmakShemirani I'm using VS and with care (UTF-8 source, BMP codepoints, `/utf-8` compiler switch, code page 65001) it works fine as I demonstrated. `_setmode` works better and requires much less care . OP wanted it to work with `printf` and it is possible, if painful. – Mark Tolonen Oct 21 '21 at 23:34
0

The best option in Windows is to use UTF16 with _setmode as shown in other answers. You can also _setmode to switch back and forth between Unicode and ANSI.

warning C4566: character represented by universal-character-name '\u221E' cannot be represented in the current code page (1252)

That's because your *.cpp file is probably saved in Unicode, the compiler sees as 2-byte UTF16 wchar_t ('\u221E') and can't convert it to char.

printf("\xEC") might print , but only on English systems, and only if the console font feels like interpreting it that way. Even if it worked, it may stop working tomorrow if you change some small settings. This is the old ANSI encoding which many problems, that's why Unicode was brought in.

You can use this alternate solution in Visual Studio with C++20:

SetConsoleOutputCP(CP_UTF8);
printf((const char*)u8"∞");

And this solution in Visual Studio and C++17:

SetConsoleOutputCP(CP_UTF8);
printf(u8"∞");

And who knows how it's going to change later.

But UTF16 is at least natively supported. wprintf, wcout with _setmode are more consistent.

Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • So I tried your suggestion. I had to add the headers: #include and #include to make it work. When I compiled I got Errors: E0035, E0040, E0018, E0079, and E0020 all relating to the winnt.h file. I guess I'll just have to forgo ∞ and just use "permanently" :( – Bishop Minter Oct 21 '21 at 23:41
  • Remove those headings. Add `` – Barmak Shemirani Oct 21 '21 at 23:43