Как использовать substring для кириллицы

Я читаю текст из файла в переменную text типа String. Затем мне надо из этой переменной вытащить первые 20 символов с помощью substring и вывести на oled экран. Но т.к. кириллица занимает по 2 байта, то из-за этого вытаскивается вместо 20 символов только 10 символов. Как можно просто исправить эту проблему и выводить 20 символов на экран, не смотря на то, что в этих 20 символах может быть и кириллица, и латиница?

Если байт равен 0xd0 или 0xd1, то это служебный байт, после него идет собственно байт символа кириллицы. Если байт меньше 0xc0 - то это однобайтовый символ

3 лайка

Это смотря какая кодировка, потому как D0 и D1 могут оказаться ‘Р’ и ‘С’ русскими.) Но если известно что здесь именно UTF8, тогда да.

1 лайк

Ну да, конкретно про UTF8 речь ))

2 лайка
// print UTF8 -> CP866
static void xlatPrint(char* src)
{
  while (*src) {
    uint8_t c = *src++;
    if (c == 0xD0) {
      c = *src++;
      if (c >= 0x90 && c <= 0xBF)
        c -= 0x10;
      else if (c == 1)
        c = 0xF0;
    }
    else if (c == 0xD1) {
      c = *src++;
      if (c >= 0x80 && c <= 0x8F)
        c += 0x60;
      else if (c == 0x91)
        c = 0xF1;
    }
    Printer.write(c);
  }
}


2 лайка

Как использовать substring для кириллицы

Не использовать. Стандартный класс String не имеет поддержки двухбайтных символов, поэтому самое простое - это написать свой собственный метод substring(), примерно как в сообщении выше.

1 лайк

+100500!

Причём, сделать это в классе-наследнике от String, чтобы вся остальная функциональность String сохранилась.

2 лайка

Спасибо всем за советы. Вечером попробую

Удачи!

Не плохо бы увидеть тут в теме исходник (то есть текст) функции substring изначальный.
Я просто никогда подобным не маялся и понять не могу в чем там могут быть подводные камни…

А чё у себя в IDE не посмотрите? Он же есть у Вас.

Ну, ладно, вот он:

String String::substring(unsigned int left, unsigned int right) const
{
	if (left > right) {
		unsigned int temp = right;
		right = left;
		left = temp;
	}
	String out;
	if (left >= len) return out;
	if (right > len) right = len;
	char temp = buffer[right];  // save the replaced character
	buffer[right] = '\0';	
	out = buffer + left;  // pointer arithmetic
	buffer[right] = temp;  //restore character
	return out;
}

Это смотря кому «надо»… ))

ЗЫ: Ну и чего такого я не понимаю, что должно меня ввергнуть в ступор перед кириллицей?

Вас – не знаю, а ТС, похоже, всё :frowning:

1 лайк

Видимо я не того года издания, ну или наоборот - ТС…

ЗЫ: К слову и в дополнение к словам @v258 - utf8 уже просто де#рена лет как неписаный стандарт для программистов. Я еще в году 2005-2006 использовал 1251, а все говорили - завязывай!))

Об этом написано в сообщениях 1, 2, 6.

Отнюдь.
Это вообще не стандарт для программистов.

А Си появился в 1972.