D Строковые литералы Юникода: невозможно напечатать определенный символ Юникода - PullRequest
0 голосов
/ 23 ноября 2018

Я просто пытаюсь подобрать D, пришедший из C ++.Я уверен, что это что-то очень простое, но я не могу найти какую-либо документацию, чтобы помочь мне.Я пытаюсь напечатать символ а , то есть U + 00E0.Я пытаюсь присвоить этот символ переменной и затем использовать write() для вывода его на консоль.

Мне сообщают на этом сайте , что U + 00E0 кодируется как 0xC3 0xA0 в UTF-8, 0x00E0 в UTF-16 и 0x000000E0 в UTF-32.

Обратите внимание, что для всего, что я пробовал, я пытался заменить string на char[]и wstring с wchar[].Я также пытался использовать суффиксы w или d после широких строк и без них.

Эти методы возвращают ошибку компилятора «Недопустимый конечный код»:

string str = "à";
wstring str = "à"w;
dstring str = "à"d;

Эти методы печатают совершенно другой символ ( Ò U + 00D2):

string str = "\xE0";
string str = hexString!"E0";

И все эти методы печатают то, что выглядит как (примечание á ≠ à!), что такое UTF-16 0x2E7 0x00E1:

string str = "\xC3\xA0";
wstring str = "\u00E0"w;
dstring str = "\U000000E0"d;

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

Я подтвердил, что это работает на моем компьютере с Windows, поэтому сейчас наберу это в качестве ответа.

В исходном коде, если вы копируете / вставляете символы напрямую, убедитесь, что ваш редактор сохраняет их вкодировка utf8.На этом настаивает D-компилятор, поэтому, если он выдает ошибку компиляции о чем-то, возможно, именно поэтому.Я никогда не использовал c: b, но старый ответ в Интернете гласил edit-> encodings ... это настройка где-то в редакторе независимо от того.

Или вы можете заменить символы в вашем исходном коде на\uxxxx в строках.НЕ используйте шестнадцатеричную строку, то есть для двоичных байтов, но ваш пример "\u00E0" хорош и будет работать для любого типа строки (не только для wstring, как в вашем примере).

Затем, насторона вывода, это зависит от вашей цели, потому что программа просто выводит байты, и программа получателя должна правильно ее интерпретировать.Поскольку вы сказали, что находитесь в Windows, ключом является установка кодовой страницы консоли в utf-8, чтобы она знала, что вы пытаетесь сделать.Действительно, та же самая функция C может быть вызвана и из D.Приводит к этой программе:

import core.sys.windows.windows;
import std.stdio;

void main() {
    SetConsoleOutputCP(65001);
    writeln("Hi \u00E0");
}

печать успешно.В старых версиях Windows вам может потребоваться изменить шрифт, чтобы увидеть символ (в отличие от общего окна, которое он показывает, потому что некоторые шрифты не имеют всех символов), но в моем окне Windows 10 он просто работал сшрифт по умолчанию.

Кстати, технически кодовая страница консоли является общей настройкой (после запуска программы и ее выхода вы все равно можете нажать свойства в окне консоли и увидеть изменения, отраженные там), и вам, возможно, следует установить ееназад, когда ваша программа выходит.Вы можете получить это при запуске с помощью функции get (https://docs.microsoft.com/en-us/windows/console/getconsoleoutputcp), сохранить ее в локальной переменной и установить обратно при выходе.Вы можете auto ccp = GetConsoleOutputCP(); SetConsoleOutputCP(65005;) scope(exit) SetConsoleOutputCP(ccp); прямо при запуске - выход из области будет запущен при выходе из функции, так что делать это в main было бы довольно удобно.Просто добавьте проверку ошибок, если хотите.

В документах Microsoft ничего не говорится об их установке, так что, вероятно, это на самом деле не имеет значения, но все же я хочу упомянуть об этом на всякий случай.Но также знание того, что оно является общим и сохраняется, может помочь в отладке - если оно работает после того, как вы прокомментируете его, это не потому, что код не нужен, а просто потому, что он был установлен ранее и еще не установлен!

Обратите внимание, что запуск его из IDE может не совпадать, потому что IDE часто направляют вывод, а не запускают его прямо на консоль Windows.Если это произойдет, позвольте мне знать, и мы можем напечатать кое-что об этом для будущих читателей.Но вы также можете открыть свою собственную копию консоли (запустить программу вне IDE), и она должна отображаться правильно для вас.

0 голосов
/ 23 ноября 2018

D исходный код должен быть закодирован как UTF-8.Я предполагаю, что вы помещаете символ UTF-16 в исходный файл UTF-8.

Например,

import std.stdio;
void main() {
    writeln(cast(char)0xC3, cast(char)0xA0);
}

Выводит в качестве UTF-8 искомый символ.

Что вы можете затем жестко кодировать так:

import std.stdio;
void main() {
    string str = "à";
    writeln(str);
}
...