Перейти к содержимому

Фото
- - - - -

Русские буквы как значения для оператора switch...case

C/C++

Лучший Ответ Володька, 19 марта 2015 - 21:20

Я в этом деле тоже не спец, поэтому может жесть получилась. У меня вроде как прокатывает такой код, хоть и ругается в некоторых местах.

Spoiler

Текст для проверки выбрал: аА - англ, аА - рус, ну и zZяЯ - соответственно.

В симуляторе вроде как в каждый case заходил когда надо.

Перейти к полному сообщению


  • Вы не можете создать новую тему
  • Please log in to reply
38 ответов в этой теме

#1 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 14:43

Строка содержит русские буквы:

char phrase[] = "АБВГДЕЖЗИ";

как в switch...case сделать их обработку?

Если делаю так:

      case 'А':
        for (int j = 0; j < 8; j++)
           to_display[i * 8 + j] = data[1][j];
          break;

      //
      case 'Б':
        for (int j = 0; j < 8; j++)
           to_display[i * 8 + j]  = data[2][j];
          break;

      //
      case 'В':
        for (int j = 0; j < 8; j++)
           to_display[i * 8 + j] = data[3][j];
          break; 

то не работает. Оно и понятно, не ASCII всё таки.  

А как сделать? 

 


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#2 Вырвиглаз

Вырвиглаз

    Убийца травы

  • Постоялец
  • 15 928 сообщений
  • Откуда:Эстония, Таллин

Отправлено 19 марта 2015 - 14:56

А зачем там вообще русские буквы? У каждого символа есть код. В данном случае компилятор пытается понять, какой код у символа 'A' и сравнивает числовые значения.


  • 0
Кто живет и грешит в Эстонии, тот опять родится в Эстонии.

#3 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 19 марта 2015 - 15:12

Вырвиглаз, ну всяко удобнее case 'A' написать, чем case 192

 

BiHiTRiLL,


 

то не работает.

Не работает - в смысле неправильно определяет код симола (unicode)? Может, через разность?


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#4 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 15:19

case 0x0410: 

для  русской "А" не срабатывает. Компилятор хавает, но на экране в этом месте пустота.

Как еще указать я не придумал


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#5 Вырвиглаз

Вырвиглаз

    Убийца травы

  • Постоялец
  • 15 928 сообщений
  • Откуда:Эстония, Таллин

Отправлено 19 марта 2015 - 15:20

Переменная в операторе switch должа быть unsigned int или long.


  • 0
Кто живет и грешит в Эстонии, тот опять родится в Эстонии.

#6 skill-AB

skill-AB

    Huge Cojones

  • Постоялец
  • 9 702 сообщений

Отправлено 19 марта 2015 - 15:21

больной, вам нужен пхп


  • -3

летела жизнь в плохом автомобиле и вылетала с выхлопом в трубу


#7 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 15:23

Переменная в операторе switch должа быть unsigned int или long.

 

попробовал уже и long и word и int. Не работает


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#8 Вырвиглаз

Вырвиглаз

    Убийца травы

  • Постоялец
  • 15 928 сообщений
  • Откуда:Эстония, Таллин

Отправлено 19 марта 2015 - 15:24

А если так?

const unsigned int LeterA = 'А';

Посмотрите, что там в дебаге.


  • 0
Кто живет и грешит в Эстонии, тот опять родится в Эстонии.

#9 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 15:34

А если так?

const unsigned int LeterA = 'А';

Посмотрите, что там в дебаге.

не сработало. LetterA принимает значение FFFFD090 если в кавычках русская "А"


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#10 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 16:45

Вот нашел код для морзянки.

 

[spoiler='код']
#define OUT 10
int spd = 50;
int freq = 875;
void setup(){
  Serial.begin(9600);
}
void loop(){
  coder("абв");
  //morze("...---...",9);
  delay(3000);
}
void coder(char* str){
  int len = 0;
  len = strlen(str);
  coder(str, len);
}
void coder(char* str,int len){
 byte table = 0;
 byte sym = 0;
 for(int i=0;i<len;i++){
  sym = (byte)str[i];
  switch(table){ //Преобразуем в заглавные буквы
    case 0xD0 :
    if(sym > 0xAF){
      sym -= 0x20;
    }
    table = 0;
    break;
    case 0xD1 :
    if(sym > 0x7F){
      sym += 0x20;
    }
    table = 0;
    break;
    case 0:
    if(sym > 0x60 && sym<0xD0){
      sym -= 0x20;
    }
  }
  //Serial.print("num = ");
  //Serial.print(i);
  //Serial.print("; code = ");
  //Serial.println(sym,HEX);
  switch(sym){
    case 0xD0: //Обработка кода таблицы
    case 0xD1:
    //Serial.println("table set");
    table = (byte)str[i];
    break;
    case '.':
    morze("......",6);
    break;
    case ',':
    morze(".-.-.-",6);
    break;
    case '/':
    morze("-..-.",5);
    break;
    case '?':
    morze("..--..",6);
    break;
    case '!':
    morze("--..--",6);
    break;
    case '@':
    morze(".--.-.",6);
    break;
    case '1':
    morze(".----",5);
    break;
    case '2':
    morze("..---",5);
    break;
    case '3':
    morze("...--",5);
    break;
    case '4':
    morze("....-",5);
    break;
    case '5':
    morze(".....",5);
    break;
    case '6':
    morze("-....",5);
    break;
    case '7':
    morze("--...",5);
    break;
    case '8':
    morze("---..",5);
    break;
    case '9':
    morze("----.",5);
    break;
    case '0':
    morze("-----",5);
    break;
    case 'A'://лат
    case 0x90://рус А
    morze(".-",2);
    break;
    case 'B'://лат
    case 0x91://рус Б
    morze("-...",4);
    break;
    case 'W'://лат
    case 0x92://рус В
    morze(".--",3);
    break;
    case 'G'://лат
    case 0x93://рус Г
    morze("--.",3);
    break;
    case 'D'://лат
    case 0x94://рус Д
    morze("-..",3);
    break;
    case 'E'://лат
    case 0x95://рус Е
    morze(".",1);
    break;
    case 'V'://лат
    case 0x96://рус Ж
    morze("...-",4);
    break;
    case 'Z'://лат
    case 0x97://рус З
    morze("--..",4);
    break;
    case 'I'://лат
    case 0x98://рус И
    morze("..",2);
    break;
    case 'J'://лат
    case 0x99://рус Й
    morze(".---",4);
    break;
    case 'K'://лат
    case 0x9A://рус К
    morze("-.-",3);
    break;
    case 'L'://лат
    case 0x9B://рус Л
    morze(".-..",4);
    break;
    case 'M'://лат
    case 0x9C://рус М
    morze("--",2);
    break;
    case 'N'://лат
    case 0x9D://рус Н
    morze("-.",2);
    break;
    case 'O'://лат
    case 0x9E://рус О
    morze("---",3);
    break;
    case 'P'://лат
    case 0x9F://рус П
    morze(".--.",4);
    break;
    case 'R'://лат
    case 0xA0://рус Р
    morze(".-.",3);
    break;
    case 'S'://лат
    case 0xA1://рус С
    morze("...",3);
    break;
    case 'T'://лат
    case 0xA2://рус Т
    morze("-",1);
    break;
    case 'U'://лат
    case 0xA3://рус У
    morze("..-",3);
    break;
    case 'F'://лат
    case 0xA4://рус Ф
    morze("..-.",4);
    break;
    case 'H'://лат
    case 0xA5://рус Х
    morze("....",4);
    break;
    case 'C'://лат
    case 0xA6://рус Ц
    morze("-.-.",4);
    break;
    case 0xA7://рус Ч
    morze("---.",4);
    break;
    case 0xA8://рус Ш
    morze("----",4);
    break;
    case 0xA9://рус Щ
    morze("--.-",4);
    break;
    case 0xAA://рус Ъ
    morze(".--.-.",5);
    break;
    case 'Y'://лат
    case 0xAB://рус Ы
    morze("-.--",4);
    break;
    case 'X'://лат
    case 0xAC://рус Ь
    morze("-..-",4);
    break;
    case 0xAD://рус Э
    morze("...-...",7);
    break;
    case 0xAE://рус Ю
    morze("..--",4);
    break;
    case 0xAF://рус Я
    morze(".-.-",4);
    break;    
  }  
 }  
}
void morze(char* str,int len){
 for(int i=0;i<len;i++){
  switch(str[i]){
   case '.':
   tone(OUT,freq, 2*spd);
   delay(6*spd);
   break;
   case '-':
   tone(OUT,freq, 6*spd);
   delay(10*spd);
   break; 
  }
 }
 delay(10*spd);
} 
[/spoiler]

 

Но получается что в тексте кода  код русских  букв один а с клавиатуры другой. Думаю дальше

 


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#11 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 17:28

Вот еще код. Помогите выдернуть суть, кто силён в С++. Своих знаний не хватает 

[spoiler='Код']
/ include the library code:
#include <LiquidCrystal.h>
#include <dht11.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(10, 11, 12, 13, A0, A1);
int DHT11PIN = A2;
dht11 DHT11;

////////////////////////////////////////////////////////////////////
// initialize display
// 3rd parameter is a string containing some needed russian characters from "БГДЖЗИЙЛПУФЦЧШЩЬЪЫЭЮЯ"
// up to 16 letters, but recommended not more than 8, anyway, i can use 16 on my lcd :)
////////////////////////////////////////////////////////////////////
static byte addon_letters[16];
void init_rus(const char* letters_use )
{
  // custom characters
  static byte letters[][8]   = {
        { B11111, B10000, B10000, B11111, B10001, B10001, B11111, B00000 },//Б
        { B11111, B10000, B10000, B10000, B10000, B10000, B10000, B00000 },//Г
        { B01111, B01001, B01001, B01001, B01001, B11111, B10001, B00000 },//Д
        { B10101, B10101, B10101, B01110, B10101, B10101, B10101, B00000 },//Ж
        { B01110, B10001, B00001, B00110, B00001, B10001, B01110, B00000 },//З
        { B10001, B10001, B10011, B10101, B11001, B10001, B10001, B00000 },//И
        { B10101, B10101, B10011, B10101, B11001, B10001, B10001, B00000 },//Й
        { B00111, B01001, B10001, B10001, B10001, B10001, B10001, B00000 },//Л
        { B11111, B10001, B10001, B10001, B10001, B10001, B10001, B00000 },//П
        { B10001, B10001, B10001, B01111, B00001, B10001, B01110, B00000 },//У
        { B01110, B10101, B10101, B10101, B01110, B00100, B00100, B00000 },//Ф
        { B10001, B10001, B10001, B10001, B10001, B10001, B11111, B00001 },//Ц
        { B10001, B10001, B10001, B01111, B00001, B00001, B00001, B00000 },//Ч
        { B10101, B10101, B10101, B10101, B10101, B10101, B11111, B00000 },//Ш
        { B10101, B10101, B10101, B10101, B10101, B10101, B11111, B00001 },//Щ
        { B10000, B10000, B10000, B11110, B10001, B10001, B11110, B00000 },//Ь
        { B11000, B01000, B01110, B01001, B01001, B01001, B01110, B00000 },//Ъ
        { B10001, B10001, B10001, B11101, B10101, B10101, B11101, B00000 },//Ы
        { B11110, B00001, B00001, B01111, B00001, B00001, B11110, B00000 },//Э
        { B10111, B10101, B10101, B11101, B10101, B10101, B10111, B00000 },//Ю
        { B01111, B10001, B10001, B01111, B10001, B10001, B10001, B00000 },//Я
  };
  static char chars[] = {'Б','Г','Д','Ж','З','И','Й','Л','П','У','Ф','Ц','Ч','Ш','Щ','Ь','Ъ','Ы','Э','Ю','Я'};
  static byte empty[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  int index = 0, cl = sizeof(chars)/sizeof(char),i,j,symb;
  memset(addon_letters,0,sizeof(addon_letters));
  for( j = 0; j < strlen(letters_use) && j < 16; j++ )
          lcd.createChar(j, empty);

  for( j = 0; j < strlen(letters_use) && j < 16; j++ )
  {
          symb = -1;
          for( i=0; i < cl; i++ ) if( chars[i] == letters_use[j] ) { symb = i; addon_letters[index] = letters_use[j]; break; }
          if( symb != -1 ) { lcd.createChar(index, letters[symb]); index++; }
  }
}
////////////////////////////////////////////////////////////////////
// print russian chars
////////////////////////////////////////////////////////////////////
void print_rus(char *str) {
  static char rus_letters[] = {'А','В','Е','Ё','К','М','Н','О','Р','С','Т','Х'};
  static char trans_letters[] = {'A','B','E','E','K','M','H','O','P','C','T','X'};
  int lcount = sizeof(rus_letters)/sizeof(char), i, j;
  for( i=0; i<strlen(str); i++ )
  { 
        if( byte(str[i]) == 208 ) continue; // 208 ignore
        int found = 0;
        for(j=0; j < 16; j++) if( addon_letters[j] != 0 && byte(str[i]) == byte(addon_letters[j]) ) { lcd.write(j); found = 1; break; }
        if(!found) for(j=0; j < lcount; j++) if( byte(str[i]) == byte(rus_letters[j]) ) { lcd.write(trans_letters[j]); found = 1; break; }
        if(!found) lcd.write(byte(str[i]));
  }  
}
void print_rus(int x, int y, char *str) {
  lcd.setCursor(x, y);
  print_rus(str);
}
////////////////////////////////////////////////////////////////////



static byte degree[8] = { B01100, B10010, B10010, B01100, B00000, B00000, B00000, B00000 };//degree

void setup() {
  lcd.begin(16, 2);
  init_rus("УПЖЬЛ");
  lcd.createChar(7, degree);
  print_rus(0,0,"ТЕМПЕРАТУРА:");
  print_rus(0,1,"ВЛАЖНОСТЬ  :");
}

void loop() {
        int response = DHT11.read(DHT11PIN);
        if( response == DHTLIB_OK)
        { 
                lcd.setCursor(12,0);
                lcd.print(DHT11.temperature);
                lcd.write(7);
                lcd.print("C  ");
                lcd.setCursor(12,1);
                lcd.print(DHT11.humidity);
                lcd.print("%  ");
        }
        else
        {               
                lcd.clear();
                init_rus("ШИБДЧЛЖП");
                print_rus(0,0," ОШИБКА ДАТЧИКА ");
                print_rus(0,1," ТЕМП/ВЛАЖНОСТИ ");
                do { delay(1000); } while( DHT11.read(DHT11PIN) != DHTLIB_OK );
                setup();
        }
        delay(1000);
} 
[/spoiler]
  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#12 Дык

Дык
  • Постоялец
  • 10 897 сообщений
  • Откуда:/dev/null

Отправлено 19 марта 2015 - 17:53

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

Т.е вначале объявляем(init_rus), какие буквы нам будут нужны - и записываем их бит-представление в сам LCD экранчик, и в нашу таблицу (addon_letters).

Перед печатью (print_rus) смотрим, есть ли символ в основной таблице - если да, передаём его индекс, если нет - пробуем из trans_letters (ASCII). Если и там нет - то кидаем набор бит AS-IS и будь что будет ( скорее всего это значит, что это - спец. символ, типо значёк градусов и так далее)

 

Попутно управляем курсором экрана, чтоб печатать в разных местах ) 


Сообщение изменено: Akhenaton (19 марта 2015 - 18:11 )

  • 0

Вначале делаю, потом думаю :)


#13 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 19:02

Мне не нужно выводить русские символы в явном виде. Мне нужно только выделить из строки русские символы и сослаться на них в case.

Допустим сейчас:

char phrase[] = "GGGИИИWWWфффф";

G - латинская

И - русская

W - латинская

Ф - русская.

 

коды русских букв в UTF-8 

в данном случае

И - два байта FFFFFFD0 и FFFFFF98

Ф - два байта FFFFFFD1 и FFFFFF84
 
непонятно как по этим данным сослаться в case, или как их преобразовать для удобства.

Сообщение изменено: BiHiTRiLL (19 марта 2015 - 19:02 )

  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#14 Володька

Володька
  • Пользователь
  • 476 сообщений
  • Откуда:Силламяэ

Отправлено 19 марта 2015 - 21:20   Лучший Ответ

Я в этом деле тоже не спец, поэтому может жесть получилась. У меня вроде как прокатывает такой код, хоть и ругается в некоторых местах.

Spoiler

Текст для проверки выбрал: аА - англ, аА - рус, ну и zZяЯ - соответственно.

В симуляторе вроде как в каждый case заходил когда надо.


Сообщение изменено: Володька (19 марта 2015 - 21:22 )

  • 2

#15 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 19 марта 2015 - 22:25

Тогда не получится у тебя просто байт за байтом проверять, раз utf8.


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#16 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 22:35

Володька

Код работает. Сортирует и условия отрабатывает. правда, в итоговом массиве появляется дыра, видать  из-за того что два байта на русскую букву выделено. Сейчас поиграюсь с индексами. попробую убрать её.

a = (phrase[i] << 8) | (phrase[i + 1] & 0xff);

Переведите мне недалёкому что это за конструкция?


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#17 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 19 марта 2015 - 22:48

Берет два байта и считает их как 16 битное число. Big endian.


Мне только непонятно, зачем накладывается маска ff, если массив и так чаровый. Понятно, что будет приведение к бОльшему типу, но тогда приведение будет для всего выражения в правых скобках, уже после маски. Или txt[i + 1] расширяется неявно, без обнуления старшей части?


Сообщение изменено: Zero (19 марта 2015 - 22:49 )

  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#18 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 19 марта 2015 - 23:05



 Или txt[i + 1] расширяется неявно, без обнуления старшей части?

 Что значит расширяется неявно?

 

 

 

Хм... ща закипит мой разум возмущённый :)

 

задал фразу: "AАAАAАAА"                   - красные "А" русские

 

На экране имеем      "AA_AA_AA_AA_" - вместо  подчеркиваний пустое место.

 

то есть в массив to_display  после каждой русской буквы попадает лишние 8 байт. причем там нули. Откуда они?

 
[spoiler='Код пока такой']

#include "LedControl.h" // 
LedControl lc = LedControl(12, 11, 10); 


int p = 60;
unsigned char phrase[] = "AАAАAАAА";


byte to_display[(sizeof(phrase) - 1) * 8];
//char phrase[] = "aAаАzZяЯ!";
int i = 0;
int a = 0;

void scroll()
{
  for (int i = 0; i < sizeof(to_display) - 8; i++)
  {
    for (int j = 0; j < 8; j++)
      lc.setRow(0, j, to_display[i + j]);
    delay(p);
  }
}

void setup()
{
  //int main(void)
  Serial.begin (9600);

  lc.shutdown(0, false);
  lc.setIntensity(0, 0);
  lc.clearDisplay(0);

  //unsigned char to_display[]={
  //,
  //,
  //112, 248, 216, 136, 136, 216, 80, 0,
  //112, 248, 136, 136, 216, 114, 254, 0,
  //112, 248, 216, 200, 168, 184, 48, 0,
  //8, 8, 252, 254, 42, 24, 24, 0};

  byte data[100][8] =
  {
    {124, 254, 211, 17, 17, 255, 254, 0},    //A
    //{112, 248, 220, 132, 68, 252, 216, 0},   //a
    {255, 255, 82, 145, 159, 254, 96, 0},    //B
    //{254, 242, 216, 136, 136, 248, 112, 0},  //b
    {124, 254, 195, 129, 195, 198, 100, 0},  //C
    {255, 255, 130, 129, 193, 127, 30, 0},   //D
    {195, 255, 126, 145, 145, 195, 66, 0},   //E
    {193, 255, 127, 18, 17, 17, 3, 0},       //F
    {124, 254, 195, 129, 201, 123, 10, 0},   //G
    {127, 255, 136, 8, 9, 255, 254, 0},      //H
    {130, 129, 157, 255, 227, 129, 65, 0},   //I
    {80, 240, 177, 129, 135, 255, 113, 0},   //J
    {193, 255, 62, 24, 124, 198, 130, 0},    //K
    {195, 255, 126, 64, 64, 64, 128, 0},     //L
    {126, 255, 195, 30, 2, 255, 255, 0},     //M
    {127, 255, 134, 8, 49, 255, 254, 0},     //N
    {120, 254, 195, 129, 195, 254, 120, 0},  //O
    {255, 255, 34, 33, 49, 31, 30, 0},       //P
    {124, 254, 195, 145, 99, 254, 140, 0},   //Q
    {255, 255, 18, 33, 121, 207, 134, 0},    //R
    {64, 230, 143, 137, 137, 251, 114, 0},   //S
    {3, 1, 199, 255, 127, 1, 3, 0},          //T
    {121, 255, 131, 128, 128, 255, 127, 0},  //U
    {63, 127, 192, 128, 195, 127, 57, 0},    //V
    {127, 255, 192, 120, 195, 255, 126, 0},  //W
    {195, 231, 189, 24, 189, 231, 195, 0},   //X
    {3, 135, 204, 104, 57, 31, 6, 0},        //Y
    {230, 51, 155, 205, 198, 67, 97, 0}      //Z


  };


  while (phrase[i] != '\0') {
    if (phrase[i] >= 0x21 && phrase[i] <= 0x7e) {
      switch (phrase[i]) { //eng
        case 'a':
          {

            break;
          }
        case 'A':
        
          {
            for (int j = 0; j < 8; j++)
            {
              to_display[i * 8 + j]  = data[0][j];
            }
            break;
            
            
          }
        case 'z':
          {

            break;
          }
        case 'Z':
          {

            break;
          }
        case '!':
          {

            break;
          }
        default: {

            break;
          }
      }
      i++;
    } else {
      a = (phrase[i] << 8) | (phrase[i + 1] & 0xff);
      switch (a) { //rus
        case 'а':
          {

            break;
          }
        case 'А':
          {
 for (int j = 0; j < 8; j++)
        {
          to_display[i * 8 + j]  = data[0][j];
          
        }
            break;
          }
        case 'я':
          {

            break;
          }
        case 'В':
          {

            break;
          }
        default: {

            break;
          }
      }
      i = i+1;
    }
  }
}

void loop()
{
  scroll();

}
[/spoiler]

Сообщение изменено: BiHiTRiLL (19 марта 2015 - 23:07 )

  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#19 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 20 марта 2015 - 00:03

BiHiTRiLL, я не помню, как по правилам Си приведение делается. По идее т.к. а интовый, он должен расширить операнды до инта. Как это будет сделано - с обнулением старшей части или нет - я не помню, но логично что с обнулением же. Тогда неясно, зачем маску на байт накладывать, если там и так байт.

 

 


 

Хм... ща закипит мой разум возмущённый :)

А кто будет i инкрементировать, а?


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#20 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 20 марта 2015 - 00:18

BiHiTRiLL, А кто будет i инкрементировать, а?

Ну так там в конце каждой секции стоит увеличение i. В английской i++ а в русской i+2.

 

Во втором случае результат одинаковый и с i+1 и с i+2. Видимых изменений нет. так же пробел после русской "А". И, что совсем странно, не работает i++.  В этом случае я вообще впал в ступор. i+1 работает а i++ нет. 


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#21 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 20 марта 2015 - 00:30

 

В английской i++ а в русской i+2.

А?

 

i = i+1;


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#22 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 20 марта 2015 - 00:49

i+1 и с i+2  дают одинаковый результат.  С пробелом после русской "А" 

 

Если поставить i+3 тогда пробела становится два.  


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#23 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 20 марта 2015 - 02:04

Нет ли случайно какого любо указателя который смещается интерпретатором, подобно виртуальному курсору с файлах Delphi?

Может нужно просто его сдвинуть?  :hmmm:


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#24 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 20 марта 2015 - 16:07

Кажется я понял в чём беда.

 

если буква русская, то во фразе она занимает 2 байта. первый байт обрабатывается корректно, для него записано условие.  

а второй обрабатывается как есть, он не соответствует латинским буквам и результат вычисления 

a = (phrase[i] << 8) | (phrase[i + 1] & 0xff);

не находит соответствия в таблице. поэтому, похоже происходит пустая итерация и соответственно меняется индекс i и перепрыгиваем на другую букву. 

 

Понять бы еще как обойти эту беду.


Сообщение изменено: BiHiTRiLL (20 марта 2015 - 16:09 )

  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#25 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 20 марта 2015 - 20:41

BiHiTRiLL, Ты о чем? Ты не уверен, что case 'А' генерирует тот же utf-8 код, что и в строке?

 

не находит соответствия в таблице. поэтому, похоже происходит пустая итерация и соответственно меняется индекс i и перепрыгиваем на другую букву.

Ну так ты должен жестко задать условие - если код однобайтный, то посмотреть, что там за байт, потом прибавить 1. Если двухбайтный - посмотреть, что за код и прибавить ДВА.


  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#26 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 20 марта 2015 - 23:41

BiHiTRiLL, Ты о чем? Ты не уверен, что case 'А' генерирует тот же utf-8 код, что и в строке?

Ну так ты должен жестко задать условие - если код однобайтный, то посмотреть, что там за байт, потом прибавить 1. Если двухбайтный - посмотреть, что за код и прибавить ДВА.

 абсолютно. Проверил. Там закавыка  была в том, что i прибавляется по каждому байту. И по ней же считается место куда писать в значения в to_display  и в момент обработки второго байта двухбайтового значения результатов не получается, соответственно в массиве нули. Если же просто прибавлять два, то в этом случае уже в момент записи данных  индекс позиции получается отстоящим на два от предыдущего. Сейчас все сделал, просто добавил еще одну переменную-счётчик позиции.

 

[spoiler='Код']

 

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

int p = 60;
unsigned char phrase[] = "FАFАFАFА"; // В этой переменной буквы"А" - русские
 
 
unsigned char to_display[(sizeof(phrase) - 1) * 8]; // определяем размерность массива на основании длины фразы 
 
int i = 0; // Переменная-индекс для указания позиции внутри массива to_display
int a = 0; // Переменная для хранения числа-индекса для русских букв
 
 
//----------------------------------------------------- вывод массива на экран
void scroll() // 
{
  for (int i = 0; i < sizeof(to_display) - 8; i++)
  {
    for (int j = 0; j < 8; j++)
      lc.setRow(0, j, to_display[i + j]);
    delay(p);
  }
}
 //---------------------------------------------------- начальные установки программы
void setup()
{
 
  byte data[100][8] = // массив хранящий графическое изображение букв. 
  {
 //--------------------------------------------------- заглавные латинские     
    {124, 254, 211, 17, 17, 255, 254, 0},    //A - 0
    {255, 255, 82, 145, 159, 254, 96, 0},    //B
    {124, 254, 195, 129, 195, 198, 100, 0},  //C
    {255, 255, 130, 129, 193, 127, 30, 0},   //D
    {195, 255, 126, 145, 145, 195, 66, 0},   //E
    {193, 255, 127, 18, 17, 17, 3, 0},       //F - 5
    {124, 254, 195, 129, 201, 123, 10, 0},   //G
    {127, 255, 136, 8, 9, 255, 254, 0},      //H
    {130, 129, 157, 255, 227, 129, 65, 0},   //I
    {80, 240, 177, 129, 135, 255, 113, 0},   //J
    {193, 255, 62, 24, 124, 198, 130, 0},    //K - 10
    {195, 255, 126, 64, 64, 64, 128, 0},     //L
    {126, 255, 195, 30, 2, 255, 255, 0},     //M
    {127, 255, 134, 8, 49, 255, 254, 0},     //N
    {120, 254, 195, 129, 195, 254, 120, 0},  //O
    {255, 255, 34, 33, 49, 31, 30, 0},       //P - 15
    {124, 254, 195, 145, 99, 254, 140, 0},   //Q
    {255, 255, 18, 33, 121, 207, 134, 0},    //R
    {64, 230, 143, 137, 137, 251, 114, 0},   //S
    {3, 1, 199, 255, 127, 1, 3, 0},          //T
    {121, 255, 131, 128, 128, 255, 127, 0},  //U - 20
    {63, 127, 192, 128, 195, 127, 57, 0},    //V
    {127, 255, 192, 120, 195, 255, 126, 0},  //W
    {195, 231, 189, 24, 189, 231, 195, 0},   //X
    {3, 135, 204, 104, 57, 31, 6, 0},        //Y
    {230, 51, 155, 205, 198, 67, 97, 0},     //Z - 25
 //--------------------------------------------------- заглавные русские  
    {124, 254, 211, 17, 17, 255, 254, 0},    //А - 26
    {255, 255, 82, 145, 159, 254, 96, 0},    //Б
    {124, 254, 195, 129, 195, 198, 100, 0},  //В
    {255, 255, 130, 129, 193, 127, 30, 0},   //Г
    {195, 255, 126, 145, 145, 195, 66, 0},   //Д - 30
    {193, 255, 127, 18, 17, 17, 3, 0},       //Е 
    {124, 254, 195, 129, 201, 123, 10, 0},   //Ж
    {127, 255, 136, 8, 9, 255, 254, 0},      //З
    {130, 129, 157, 255, 227, 129, 65, 0},   //И
    {80, 240, 177, 129, 135, 255, 113, 0},   //Й - 35
    {193, 255, 62, 24, 124, 198, 130, 0},    //К
    {195, 255, 126, 64, 64, 64, 128, 0},     //Л
    {126, 255, 195, 30, 2, 255, 255, 0},     //М
    {127, 255, 134, 8, 49, 255, 254, 0},     //Н
    {120, 254, 195, 129, 195, 254, 120, 0},  //О - 40
    {255, 255, 34, 33, 49, 31, 30, 0},       //П
    {124, 254, 195, 145, 99, 254, 140, 0},   //Р
    {255, 255, 18, 33, 121, 207, 134, 0},    //С
    {64, 230, 143, 137, 137, 251, 114, 0},   //Т
    {3, 1, 199, 255, 127, 1, 3, 0},          //У - 45
    {121, 255, 131, 128, 128, 255, 127, 0},  //Ф
    {63, 127, 192, 128, 195, 127, 57, 0},    //Х
    {127, 255, 192, 120, 195, 255, 126, 0},  //Ц
    {195, 231, 189, 24, 189, 231, 195, 0},   //Ч
    {3, 135, 204, 104, 57, 31, 6, 0},        //Ш - 50
    {230, 51, 155, 205, 198, 67, 97, 0},     //Щ
 
  };
 
 //---------------------------------------------------- создание массива to_display
  while (phrase[i] != '\0') {
    if (phrase[i] >= 0x21 && phrase[i] <= 0x7e) {//--- определяем не латинская ли буква
      switch (phrase[i]) {  //------------------------ обрабатываем латинские буквы   
 
 case 'A': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[ 0][j];}break;
 case 'B': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[ 1][j];}break;
 case 'C': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[ 2][j];}break;
 case 'D': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[ 3][j];}break;
 case 'E': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[ 4][j];}break;
 case 'F': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[ 5][j];}break;
 case 'G': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[ 6][j];}break;
}
  i++;
  p++;
  }
 //--------------------------------------------------- обрабатываем русские буквы   
    else { 
      a = (phrase[i] << 8) | (phrase[i + 1] & 0xff); // из двух байт кодирующих русскую букву в UTF-8 делаем одно число для анализа
    i=i+2;
      switch (a) {
 case 'А': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[26][j];}break;
 case 'Б': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[27][j];}break;
 case 'В': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[28][j];}break;
 case 'Г': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[29][j];}break;
 case 'Д': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[30][j];}break;
 case 'Е': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[31][j];}break;
 case 'Ф': for (int j = 0; j < 8; j++){to_display[p * 8 + j]  = data[32][j];}break;
          }
      }
      p++;   
    }
    //i++; // можно использовать один инкремент. если он одинаковый.
  }
}
 //--------------------------------------------------- основной цикл
void loop()
{
  scroll(); // Вызываем вывод массива на экран
 
} 
[/spoiler]

 

Грабли вылезли на ровном месте. Не могу задать длину массива  to_display  на основании длины phrase. Если делать через sizeof то на русскую букву считает два байта. А нужно просто посчитать количество символов в строке, а я не знаю пока как.


Сообщение изменено: BiHiTRiLL (20 марта 2015 - 23:44 )

  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#27 Дык

Дык
  • Постоялец
  • 10 897 сообщений
  • Откуда:/dev/null

Отправлено 20 марта 2015 - 23:56

Т.е хочешь сказать, что у тебя sizeof( phrase ) = 13?


  • 0

Вначале делаю, потом думаю :)


#28 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 21 марта 2015 - 00:13

 

А нужно просто посчитать количество символов в строке, а я не знаю пока как.

Тебе нужна специальная функция, которая высчитывает длину строки, как strlen(phrase), только та, что понимает UTF-8.

 

И to_display тебе надо создавать динамически, через new, как выше показывал тебе Серджио.

 

 

Точнее, даже не так - определи, что тебе важнее - память или скорость. Если скорость, то сначала создать to_display как sizeof, он будет больше, чем надо. При проходе по строке считай символы, еще одну переменную добавь. Потом усеки массив.

Если важна память, то надо будет делать два прохода - сначала длину найти, потом уже сами символы смотреть. Хотя хз, сколько займет усечение.

 

Akhenaton, у него русские символы в utf-8 хранятся.


Сообщение изменено: Zero (21 марта 2015 - 00:14 )

  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#29 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 21 марта 2015 - 00:43

Т.е хочешь сказать, что у тебя sizeof( phrase ) = 13?

 

В примере выше - да.


Точнее, даже не так - определи, что тебе важнее - память или скорость. Если скорость, то сначала создать to_display как sizeof, он будет больше, чем надо. При проходе по строке считай символы, еще одну переменную добавь. Потом усеки массив.

Если важна память, то надо будет делать два прохода - сначала длину найти, потом уже сами символы смотреть. Хотя хз, сколько займет усечение.

 

 

Пошел читать как всё это делается... Я тот еще прогер


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#30 Дык

Дык
  • Постоялец
  • 10 897 сообщений
  • Откуда:/dev/null

Отправлено 21 марта 2015 - 10:41

Сделай свой калькулятор с блекджеком и т.д - вначале регистрируй те русские буквы, которые будешь юзать в таблицу (для пущей эффективности память можешь выделять динамически - malloc, realloc), и при подсчёте длины строки запрашивай таблицу - есть ли буква в таблице и если есть, то отнимай 2 (или какой там у нее sizeof), если нет, отнимай 1 и это всё дело в цикле пока не дойдешь от sizeof(phrase) до 0 - инкрементируй счётчик.


Сообщение изменено: Akhenaton (21 марта 2015 - 10:45 )

  • 0

Вначале делаю, потом думаю :)