Как преобразовать символ Unicode в «Unicode HEX Position» в Arduino

Как преобразовать символ Юникода в "Шестнадцатеричная позиция Юникода" в Arduino или C

я поделюсь здесь картинкой:

например, в JavaScript вы можете сделать это с помощью charCodeAt(); ! эта функция вернет именно символьный код, а затем вы сможете преобразовать его в шестнадцатеричный!

например, в JavaScript я могу сделать так, чтобы вернуть точное значение таблицы

 var inpString = 'س';
    var myChar=0;
    var output = 0;
    myChar = inpString.charCodeAt(0);
    output = (ToHex((myChar&0xff00)>>8 )) + (ToHex( myChar&0xff ));
    
    function ToHex(i)
    {
        var sHex = "0123456789ABCDEF";
        var Out = "";
        Out = sHex.charAt(i&0xf);
        i>>=4;
        Out = sHex.charAt(i&0xf) + Out;
        return Out;
    }
 alert(output);

Итак, как я могу сделать это в Arduino? его использование для отправки символа Unicode в режиме PDU в Arduino мне просто нужно преобразовать юникодный символ следующим образом -> 'س', чтобы исправить позицию Unicode HEX, которую я поделил на картинке выше

например, «س» — это 0633, или «A» — это 0041, или «ب» — это 067E

, 👍2

Обсуждение

Или просто console.log("س".charCodeAt(0).toString(16))., @Edgar Bonet

пожалуйста, не размещайте сообщения в нескольких местах... https://stackoverflow.com/questions/62878287/how-to-convert-unicode-char-to-unicode-hex-position-in-arduino-or-c, @jsotola


3 ответа


Лучший ответ:

1

В отличие от JavaScript, в C++ нет разницы между символом и его кодовая точка. Таким образом, 'A', 0x41 и 65 — это просто разные способы написание одного и того же числа.

Обратите внимание, однако, что тип char предназначен для хранения только ASCII. За во всем остальном вы можете попробовать использовать широкие символы. Например, программа

void setup() {
    Serial.begin(9600);
    wchar_t c = L'س';
    Serial.println(c, 16);
}

void loop() {}

выводит 633 на последовательный порт. Обратите внимание на второй аргумент Serial.println(), который указывает основание 16. По умолчанию используется для печати числа в десятичном формате.

Остерегайтесь того, что представление широких символов является реализацией определены, а avr-libc не поддерживает управление ими. или строки из них. Если вы хотите передать их, вы также должны решить для себя, как разбить их на последовательность байтов, так как это единственный последовательный порт (или I2C, или SPI для этого материя) может передавать. UTF-8 — самый популярный выбор. я сомневаюсь широко символы вообще популярны во встроенных системах.

,

это работает, вы потрясающие, большое спасибо, @ermya

поэтому отличие от скетча в моем ответе заключается в кодировке исходного кода по сравнению с кодировкой Serial Monitor., @Juraj

@Juraj: кодировка исходного кода не имеет отношения к моему ответу, если среда разработки непротиворечива (та же кодировка, используемая редактором и предполагаемая компилятором): компилятор инициализирует c кодовой точкой символа, редактор показывает между кавычками. По сути, это эквивалентно написанию wchar_t c = 0x633, но, как мы надеемся, будет иметь больше смысла для программиста. Как только программа выполняет ввод-вывод с символами, отличными от ASCII, она должна будет принять решение о кодировке символов, которую она собирается использовать., @Edgar Bonet


0

Это будет считывать и печатать символы Юникода из/в Serial Monitor и печатать их HEX-коды. Установите строку, заканчивающуюся в Serial Monitor, на NL и подтвердите введенный символ, нажав Enter.

void setup() {
  Serial.begin(115200);
}

void loop() {
  if (Serial.available()) {
    char buff[4];
    int l = Serial.readBytesUntil('\n', buff, sizeof(buff) - 1);
    if (l > 0) {
      buff[l] = 0;
      Serial.println(buff);
      Serial.print(buff[0], HEX);
      if (l > 1) {
        Serial.print(buff[1], HEX);
      }
      Serial.println();
    }
  }
}
,

спасибо за ответ, этот код напечатайте -> D8B3 for -> 'س', а не 0633! но он работает правильно для символа ascii, @ermya

1. Если buff[0] меньше 16, вам придется дополнить нулями. 2. Эта программа предполагает, что последовательный монитор отправляет символы как [UCS-2BE](http://justsolve.archiveteam.org/wiki/UCS-2), что не так. Как почти все в наши дни, он использует UTF-8 для ввода и вывода., @Edgar Bonet

@EdgarBonet, мой набросок ничего не предполагает. он печатает шестнадцатеричные значения, и я знаю, что это UTF-8. и видимые символы имеют коды> 0x10, @Juraj

Вопрос заключается в печати _кодовой точки_ (а не _кодовых единиц_!) символа в шестнадцатеричном формате. Ваш скетч печатает шестнадцатеричные значения _пар байтов_, объединенных в конкатенацию. То, как они соединяются, подразумевает неявное предположение, что эти байты представляют собой 16-битные числа, передаваемые в порядке байтов с обратным порядком байтов. Рассмотрение этих 16-битных чисел как эквивалентных кодовым точкам допустимо только в том случае, если символы передаются как UCS-2., @Edgar Bonet


0

Надежный способ вывода символов Unicode – использовать восьмеричные эквиваленты в печатаемой строке. например

Serial.print("\342\204\211");

будет выводить ℉, если у получателя есть шрифт для этого юникода.

Использование символов, отличных от ASCII, в Arduino имеет файл .jar, который преобразует символы Unicode, строки \u... и восьмеричные числа

Hex \x.. не используется, потому что компиляторы C могут запутаться, если следующий символ после двух шестнадцатеричных цифр будет от 'a' до 'f'. Использование восьмеричного числа позволяет избежать этой проблемы. Компилятор GCC, используемый Arduino, также не принимает все последовательности Unicode, такие как \u0020.

,