Создание строк с символами UTF-8 из данных
Я печатаю некоторые изображения ASCII на последовательном мониторе из Arduino UNO, и с некоторым успехом. Однако использование строковых литералов требует больше памяти, чем хотелось бы. Я хотел попробовать создать строки/символы из других типов данных, чтобы можно было манипулировать данными и печатать ascii-изображения, не сохраняя их в строковых литералах.
Однако я обнаружил, что, похоже, нет другого способа напечатать символы UTF-8, кроме как из строкового литерала. Так ли это? Нет ли способа создать строку, содержащую символы, числовые значения которых слишком велики для char
?
Например, чтобы напечатать "▓" отлично работает как строковый литерал, но, судя по всему, не иначе.
Serial.println("▓"); // работает отлично
Serial.println('▓'); // char не может хранить значение
Serial.println(String('▓')); // char не может хранить значение
Serial.println(0x2593); // просто печатаем числовое значение
Serial.println((char)0x2593); // char не может хранить значение
Serial.println((wchar_t)0x2593); // не работает
Serial.println(String(0x2593)); // не работает
Serial.println(String((wchar_t)0x2593)); // не работает
Аналогично с write() вместо print():
Serial.write("▓"); // Работает отлично
Serial.write('▓'); // char не может хранить значение
Serial.write(0x2593); // просто печатаем числовое значение
Serial.write((char)0x2593); // char не может хранить значение
Serial.write((wchar_t)0x2593); // не работает
Я также пытался получить строки новых компонентов из строкового литерала, используя substring()
и charAt()
. Ни то, ни другое не работает. Оба выдают � на выходе.
String((char)65)
создает строку "A" из числового значения 65. Ни String((char)0x2593)
, ни String((wchar_t)0x2593)
не дают желаемых результатов. Есть ли способ создать строку из числовых значений, которые слишком велики для хранения в «char»?
@Hubert B, 👍0
Обсуждение1 ответ
Как вы заметили, Serial
не знает, как обращаться с wchar_t
.
Если вы создаете свои строки алгоритмически из кода Unicode
точки, вам необходимо преобразовать эти кодовые точки в UTF-8 для печати. я
мне не известно ни о какой встроенной функции, которая бы это делала. Возможно, вы захотите
найдите в менеджере библиотеки библиотеку, предоставляющую эту функцию.
Альтернативно вы можете написать преобразование самостоятельно: это не то сложный. Например, вот функция, которая преобразует любой код указывает из BMP (т. е. < 216) на строку UTF-8:
// Многобайтовый символ BMP с завершающим нулевым байтом.
struct Mbchar {
char utf8[4];
};
// Преобразование широкого символа в UTF-8. Работает только внутри BMP.
Mbchar wchar_to_utf8(wchar_t c) {
Mbchar result;
if (c < 128) { // 0xxx.xxxx
result.utf8[0] = c;
result.utf8[1] = 0;
} else if (c < 2048) { // 110x.xxxx 10xx.xxxx
result.utf8[0] = 0xc0 | (c >> 6);
result.utf8[1] = 0x80 | (c & 0x3f);
result.utf8[2] = 0;
} else { // 1110.xxxx 10xx.xxxx 10xx.xxxx
result.utf8[0] = 0xe0 | (c >> 12);
result.utf8[1] = 0x80 | (c >> 6 & 0x3f);
result.utf8[2] = 0x80 | (c & 0x3f);
result.utf8[3] = 0;
}
return result;
}
Имейте в виду, что в зависимости от используемого вами Arduino wchar_t
может
не поддерживает символы вне BMP. Arduino на базе AVR
определенно нет.
Эту функцию можно использовать следующим образом:
Serial.println(wchar_to_utf8(0x2593).utf8); // prints “▓”
Возможно, стоит добавить, что их использование '▓'
не приведет к созданию типа 'wchar_t
, а просто создаст какое-то бесполезное значение 'char
. Им понадобится L'▓'
, который они смогут использовать вместе с вашим кодом в Serial.println(wchar_to_utf8(L'▓').utf8);
, @timemage
- Arduino Serial.ReadString() проблема
- String() против char для простого управления потоком
- Как анализировать многострочные последовательные данные с неизвестным количеством строк?
- Проблема с очисткой строки, считанной из последовательного буфера
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- Как получить тип данных переменной?
- форматирование строк в Arduino для вывода
попробуйте
Serial.println("\u2593");
, @jsotolaЯ бы попробовал распечатать массивы байтов, содержащие сериализацию UTF-8, а не числовой код. Например \xe2 ,\x96, \x93 вместо \u2593., @RedGrittyBrick