Как корректно подсчитать длину строки, если в ней смесь кириллицы и латиницы?
- Войдите на сайт для отправки комментариев
Ср, 05/03/2014 - 14:30
Началось все с того, что функция вывода строки по центру стала себя плохо вести при выводе сообщений на русском языке.
Оказалось, что длина строки, вычисляемая через .lenght, не совпадает с реальным количеством знаков:
String msgEng = "12345 Test message ";
String msgRus = "Тестовое сообщение ";
String msgRusEng = "Тестовое 12message ";
void setup()
{
Serial.begin(9600);
Serial.print("msgEng:"); Serial.println(msgEng.length());
Serial.print("msgRus:"); Serial.println(msgRus.length());
Serial.print("msgRusEng:"); Serial.println(msgRusEng.length());
}
void loop()
{ }
Результат:
msgEng:19 msgRus:36 msgRusEng:27
на русскую букву 2 байта.
а раньше было по другому?
Раньше не было необходимости использовать кириллицу, поэтому не знаю ;)
Сочинен вот такой код, который верно считает длину строки:
//char msg[] = "012345 Test message."; char msg[] = "012345 Пример текста"; void setup() { Serial.begin(9600); byte i,count=0; //Serial.println(msg); while (msg[i] != '\0') { //Serial.print((int)(msg[i])); // чтобы понять, как записывается символ "внутри" //Serial.print(" "); if (msg[i] < ' ') i=i+2; // если кириллический символ, то проскакиваем следующий шаг else i++; count++; } Serial.print("\nCount:"); Serial.println(count); } void loop() {}Но... как-то это неоптимально, на мой взгляд. Есть ли менее ресурсоемкий способ?
на русскую букву 2 байта.
а раньше было по другому?
то, что на экране символ занимает одно знакоместо совсем не означает, что это однобайтовый символ
на русскую букву 2 байта.
а раньше было по другому?
size_t LiquidCrystalRus::write(uint8_t value) { uint8_t out_char=value; if (_dram_model == LCD_DRAM_WH1601) { uint8_t ac=recv(LOW) & 0x7f; if (ac>7 && ac<0x14) command(LCD_SETDDRAMADDR | (0x40+ac-8)); } if (value>=0x80) { // UTF-8 handling if (value >= 0xc0) { utf_hi_char = value - 0xd0; } else { value &= 0x3f; if (!utf_hi_char && (value == 1)) send(0xa2,HIGH); // ╗ else if ((utf_hi_char == 1) && (value == 0x11)) send(0xb5,HIGH); // ╦ else send(pgm_read_byte_near(utf_recode + value + (utf_hi_char<<6) - 0x10), HIGH); } } else send(out_char, HIGH); return 1; // assume sucess }Как то так, но в этом случае не мешало бы и остальные символы нарисовать. не очень понятно чем вообще обоснована затея держать в ардуине символы UTF? Разве что обрабатывать что то пришедшее с наружи... Но тогда было бы логично делать полную обработку, не ограничиваясь только кириллицей.
ребята, вы о чем? Мне нужно было выравнивать строку на LCD по центру, для этого было необходимо знать, сколько символов (физических знакомест) она занимает. Проблема решена - выражение .lenght заменено самописной функцией, пусть неоптимальной, но рабочей. :)
"А мужики то не знают!"(с) ))
Впрочем, кроме одной задачи нашлись решения для сопутствующих...