wchar_t в char

Тема в разделе "Arduino & Shields", создана пользователем Lism, 22 фев 2015.

  1. Lism

    Lism Нерд

    Здравствуйте. У меня есть массив типа wchar_t где храниться Unicode-строка. Оттуда символ передаётся в функцию. Если там оказывается кириллица, то в switch'е она преобразуется в коды МЭЛТ-дисплея. Иначе символ является или латиницей, или цифрой, и символ возвращается без изменений. Но как перевести символ wchar_t в char?
     
  2. Alex19

    Alex19 Гуру

    Любопытный тип данных, до этого ни когда не сталкивался. Его размер 2 байта.
    Код (Text):
    int sizeOfWchar_t = sizeof(wchar_t);
    Serial.println(sizeOfWchar_t);
    А у char, размер 1 байт. Без потери, преобразовать wchar_t в char, не получится.

    Вариантов несколько, можно попробовать проверять в switch, сами wchar_t.
    Так же посмотрите тут.
     
  3. Lism

    Lism Нерд

    В стандартной библиотеке такой функции нет. =\ Надо самому её писать.

    --UPD--

    Я хотел транслировать латиницу хранимую в wchar_t в аналогичные символы char. Просто у меня программа берёт из переменной строку на русском и выводит на МЭЛТ-дисплей. Для хранения кириллицы внутри программы надо использовать wchar_t.
     
  4. Alex19

    Alex19 Гуру

    Не очень понимаю, что за библиотека, когда-то сделал так. И зачем - для хранения кириллицы внутри программы надо использовать wchar_t.

    Просто исправьте
    Код (Text):
        if (keyArray == -1)
        {
          // Ошибка
          //Serial.println(cBuffer[i]);
        }
        else
        {
          //lcd.print(rusCodeKeys[keyArray]);
        }
    На
    Код (Text):
        if (keyArray == -1)
        {
          // Анг.
          lcd.print(cBuffer[i]);
        }
        else
        {
          // Рус.
          lcd.print(rusCodeKeys[keyArray]);
        }
    Надо оптимальнее, тогда меняем типы на uint8_t, PROGMEM и т.д.

    UPD. Возможно еще оптимальнее, давно с LCD не работал, поэтому скинул, в чем уверен.
    UPD2. Думаю с switch, будет оптимальнее, но все равно не понимаю зачем там wchar_t, проверяйте char.
     
    Последнее редактирование: 22 фев 2015
  5. Lism

    Lism Нерд

    Просто она русская буква это два байта. А в char 1 байт.
    Если сделаем так:
    Код (Text):
    char chars[] = "Русские символы.";
    char first = chars[0];
    //Или так.
    String string = "Русские символы";
    char firstFromString = string[0];
    То в переменной будет не 'Р', а что-то другое.

    --UPD--
    Почитай про кодировки и поймёшь о чём я.

    --UPD2--
    Вот код функции, кому нужен.

    Код (Text):
    char wcharToChar(wchar_t wchar){
      switch(wchar){
     
        case L'A':
          return 'A';
        break;
     
        case L'B':
          return 'B';
        break;
     
        case L'C':
          return 'C';
        break;
     
        case L'D':
          return 'D';
        break;
     
        case L'E':
          return 'E';
        break;
     
        case L'F':
          return 'F';
        break;
     
        case L'G':
          return 'G';
        break;
     
        case L'H':
          return 'H';
        break;
     
        case L'I':
          return 'I';
        break;
     
        case L'J':
          return 'J';
        break;
     
        case L'K':
          return 'K';
        break;
     
        case L'L':
          return 'L';
        break;
     
        case L'M':
          return 'M';
        break;
     
        case L'N':
          return 'N';
        break;
     
        case L'O':
          return 'O';
        break;
     
        case L'P':
          return 'P';
        break;
     
        case L'Q':
          return 'Q';
        break;
     
        case L'R':
          return 'R';
        break;
     
        case L'S':
          return 'S';
        break;
     
        case L'T':
          return 'T';
        break;
     
        case L'U':
          return 'U';
        break;
     
        case L'V':
          return 'V';
        break;
     
        case L'W':
          return 'W';
        break;
     
        case L'X':
          return 'X';
        break;
     
        case L'Y':
          return 'Y';
        break;
     
        case L'Z':
          return 'Z';
        break;
     
        case L'a':
          return 'a';
        break;
     
        case L'b':
          return 'b';
        break;
     
        case L'c':
          return 'c';
        break;
     
        case L'd':
          return 'd';
        break;
     
        case L'e':
          return 'e';
        break;
     
        case L'f':
          return 'f';
        break;
     
        case L'g':
          return 'g';
        break;
     
        case L'h':
          return 'h';
        break;
     
        case L'i':
          return 'i';
        break;
     
        case L'j':
          return 'j';
        break;
     
        case L'k':
          return 'k';
        break;
     
        case L'l':
          return 'l';
        break;
     
        case L'm':
          return 'm';
        break;
     
        case L'n':
          return 'n';
        break;
     
        case L'o':
          return 'o';
        break;
     
        case L'p':
          return 'p';
        break;
     
        case L'q':
          return 'q';
        break;
     
        case L'r':
          return 'r';
        break;
     
        case L's':
          return 's';
        break;
     
        case L't':
          return 't';
        break;
     
        case L'u':
          return 'u';
        break;
     
        case L'v':
          return 'v';
        break;
     
        case L'w':
          return 'w';
        break;
     
        case L'x':
          return 'x';
        break;
     
        case L'y':
          return 'y';
        break;
     
        case L'z':
          return 'z';
        break;
     
        case L' ':
          return ' ';
        break;
     
        case L'0':
          return '0';
        break;
     
        case L'1':
          return '1';
        break;
     
        case L'2':
          return '2';
        break;
     
        case L'3':
          return '3';
        break;
     
        case L'4':
          return '4';
        break;
     
        case L'5':
          return '5';
        break;
     
        case L'6':
          return '6';
        break;
     
        case L'7':
          return '7';
        break;
     
        case L'8':
          return '8';
        break;
     
        case L'9':
          return '9';
        break;
     
        case L'.':
          return '.';
        break;
     
        case L',':
          return ',';
        break;
     
        case L'!':
          return '!';
        break;
     
        case L'?':
          return '?';
        break;

        case L'@':
          return '@';
        break;
     
        case L'#':
          return '#';
        break;
     
        case L'$':
          return '$';
        break;
     
        case L'%':
          return '%';
        break;
     
        case L'^':
          return '^';
        break;
     
        case L'&':
          return '&';
        break;
     
        case L'*':
          return '*';
        break;
     
        case L'(':
          return '(';
        break;
     
        case L')':
          return ')';
        break;
     
        case L'-':
          return '-';
        break;
     
        case L'_':
          return '_';
        break;
     
        case L'=':
          return '=';
        break;
     
        case L'+':
          return '+';
        break;
     
        case L'\\':
          return '\\';
        break;
     
        case L'/':
          return '/';
        break;
     
        case L'|':
          return '|';
        break;
     
        case L'`':
          return '`';
        break;
     
        case L'~':
          return '-';
        break;
     
        case L'<':
          return '<';
        break;
     
        case L'>':
          return '>';
        break;
     
        case L'\"':
          return '\"';
        break;
     
        case L'\'':
          return '\'';
        break;
     
        case L';':
          return ';';
        break;
     
        case L':':
          return ':';
        break;
      }
    }
     
    Последнее редактирование: 22 фев 2015
    Alex19 нравится это.
  6. geher

    geher Гуру

    Будет первый байт кода в UTF-8 для буквы Р,
    В Arduino IDE кодировка текста вроде как UTF-8. Т.е. латинской букве соответствует один байт, кириллице - два байта. Некоторым символам может соответствовать еще больше байт, до шести, если не ошибаюсь. Это надо учитывать при перекодировании.

    Если работать с wchar_t, то имеем дело с UTF-16, в которой любому символу соответствует два байта (ардуиновский int). С ним иметь дело проще, но если в тексте присутствует латиница, в памяти занимает больше места.
    В этом случае для латиницы (и вообще для любого символа с кодом меньше 128) достаточно присвоить значение без преобразования.
    wchar_t ws[10]=L"Latin Русский";
    char c=ws[1];
    в переменной с будет 'a';
     
    Последнее редактирование: 22 фев 2015
  7. Alex19

    Alex19 Гуру

    Не знал, моя ардуина говорит, что 1
    Код (Text):
    char temp = 'Ф';
    Serial.println(sizeof(temp));
    Предлагал отказаться от wchar_t.

    Хорошее решение, вопросов нет. Рад, что Вы сами разобрались.

    Вы говорили о экране МЭЛТ, вот файл с описанием, стр. 8-9.
    В массиве хранятся не символы а код символа, от 00 до FF, другими словами от 0 до 255, то есть 1 байт. Тот код, на который давал ссылку, работал в одном из моих проектов и работал как часы в течении месяца.

    UPD. Возможно он его обрезает, при сохранении в char, любопытно, почему он тогда работал.
    UPD2. Все разобрался, у меня массив 2-ной.
     
    Последнее редактирование: 22 фев 2015
  8. geher

    geher Гуру

    Правильно говорит. Поскольку он говорит не про размер конкретного, символа, а про размер элемента массива. Просто русская буква занимает два элемента массива.
    А после char temp = 'Ф'; в temp будет A4 (какой-то символ псевдографики в ANSI), в то время как 'Ф' - это нечто двухбайтовое (0xD0A4), только начинающееся с A4 (младший байт кода).
     
    Alex19 нравится это.
  9. Lism

    Lism Нерд

    Просто я реализовал бегущую строку, и мне надо было чтоб все символы были в МЭЛТ-формате. Буквы в кодировку МЭЛТ-дисплея я переводил по одной, и разный размер выдавал что-то вроде ",Эndex". Но после переписания кода под двухбайтовые символы латиница перестала обрабатываться (символы в МЭЛТ-кодировке я храню в обычных char'ах.), и мне пришлось подумать о переводе из wchar_t в char.
     
  10. Alex19

    Alex19 Гуру

    Да Вы правы, а не заметил, потому-то почти не пересекались.

    UPD. Вроде, всего 2 пересечения:(, в моем массиве. Но есть, данный код может дать сбой.