Как сделать лучше?
- Войдите на сайт для отправки комментариев
Чт, 28/02/2019 - 19:58
Есть функция:
void _setTime() { byte h = Clock.getHour(h12, PM);// получаем часы byte m = Clock.getMinute(); // минуты byte s = Clock.getSecond(); // и секунды из ds3231 // проверка на количество разрядов в hh mm и ss и печать на экран 2004. Если что-то меньше 10, //печатаем пробел перед цифрой if ((h >= 10) & (m >= 10) & (s >= 10)) lcd.printfAt(5, 1, "%d:%d:%d", h, m, s); else if ((h < 10) & (m >= 10) & (s >= 10)) lcd.printfAt(5, 1, " %d:%d:%d", h, m, s); // если часы меньше 10, печатаем пробел перед ними else if ((h >= 10) & (m < 10) & (s >= 10)) lcd.printfAt(5, 1, "%d: %d:%d", h, m, s); else if ((h >= 10) & (m >= 10) & (s < 10)) lcd.printfAt(5, 1, "%d:%d: %d", h, m, s); else if ((h >= 10) & (m < 10) & (s < 10)) lcd.printfAt(5, 1, "%d: %d: %d", h, m, s); else if ((h < 10) & (m >= 10) & (s < 10)) lcd.printfAt(5, 1, " %d:%d: %d", h, m, s); else if ((h < 10) & (m < 10) & (s >= 10)) lcd.printfAt(5, 1, " %d: %d:%d", h, m, s); else lcd.printfAt(5, 1, " %d: %d: %d", h, m, s); h = lcd.inputTimeHourAt(5, 1, 0, 23, h);// функция ввода с помощью энкодера и печати. номер, строка, //нижний лимит, верхний лимит, значение по умолчанию. Clock.setClockMode(false); Clock.setHour(h); m = lcd.inputTimeMinAt(7, 1, m); Clock.setMinute(m); s = lcd.inputTimeSecAt(10, 1, s); Clock.setSecond(s); while (lcd.getEncoderState() != eButton); }
Она вызывается обработчиком меню. lcd.printfAt() функция библиотеки этого самого меню. Она основана на printf, и выводит строку с нужной позиции на lcd 2004. Все работает, но мне не нравится код с if и else if, вероятно можно краше как то. По сути вопрос, можно ли как-то изменять форматирующую строку printf, то есть добавлять пробелы в зависимости от количества разрядов выводимого?
Ага, уже ответили.
Да пробовал, printf в ардуине урезаный, не работает.
upd Все работает, круто. Спасибо!
Не урезанный, стало быть, или урезанный таки? Мужики спрашивают, волнуются...
%f у его обрезанный. Дак добрые луди пользують dtostr()
%f у его обрезанный. Дак добрые луди пользують dtostr()
Спасибо, чуствую пригодится.
А как вместо нуля пробел печатать?
Выравнивать. Влево или вправо. Чти, я не помню.
Круто, чту.
А как вместо нуля пробел печатать?
Ноль убрать
или
как больше нравится (это разное выравнивание)
%f у его обрезанный.
У него не %f обрезанный.
printf получает адрес переменной и по указанному в текстовой строке формату считает, что по стандарту Си там должна лежать нормальная 8-байтовая double. А у AVR double имеет длину 4 байта, вот и получается облом. Кстати, на Due и stm32 этой проблемы нет, т.к. там обычная 64-разрядная double. И, соответственно, printf нормально работает.
Так что printf работает и на Ардуино. Но не везде.
Чёт Вы напутали.
А вот как принтф отучить писать +0 при %+4ld? А то не всегда этот оптимизм уместен.
А как вместо нуля пробел печатать?
Ноль убрать
или
как больше нравится (это разное выравнивание)
Спасибо за разжевывание! Уже переписал все. Не пойму, как проглядел выравнивание.
А вот как принтф отучить писать +0 при %+4ld? А то не всегда этот оптимизм уместен.
Лучше было не приучать :)
Ибо «ваистену» сказано: «+ The result of a signed conversion always begins with a plus or minus sign» (ISO/IEC 9899-2018, разд. 7.21.6.1 (6))
:(
Температуру удобно выводить. Потому что ежели в поле с выравниванием её совать, то выходит "- 30C" на отрицательной. А с модификатором "+" всё красиво " -30C"
А модификатор "пробел"? Не подходит?
Хм... как я его просмотрел... Интересный вариант, мерси. Теперь мучений добавилось: оставить " +15" и " +0" или согласиться на " 15" и " 0" - вот в чём вопрос...
замени в буфере плюс пробелом, да и сё
ну или весь буфер влево сдвинь.
Да у меня строка составная выводится на LCD. Поэтому и snprintf заюзал - чтобы самому с выравниванием не страдать.
Поэтому и snprintf заюзал
А чем выводите? Если какой-нить бильбитекой, произведённой от Stream, так можно и без "s" - прямо printf на экран натравить.
Да у меня строка составная выводится на LCD. Поэтому и snprintf заюзал - чтобы самому с выравниванием не страдать.
Красиво! Хоть ИЭК и не люблю, но задумался над таким корпусом.
А чем выводите? Если какой-нить бильбитекой, произведённой от Stream, так можно и без "s" - прямо printf на экран натравить.
Самопалом из char[] буфера в PCF8574... Памяти в обрез, поэтому один и тот же буфер и под входные данные с сети и под вывод куда попало. Так что пока вот самый "дешёвый" для меня выход - snprintf_P(buffer, NNN, PSTR(" ... "). ...);
Ну дак найди потом в buffer[] плюсик, да замени на пробел
Да у меня строка составная выводится на LCD. Поэтому и snprintf заюзал - чтобы самому с выравниванием не страдать.
А зачем составная? Выводи каждый тип данных в свою позицию дисплея - вот тебе и выравнивание
Во-первых - это красиво...
Во-вторых: какой будет "своя" позиция при выводе числа от 0 до 99 со знаком, при условии выравнивания его по правой стороне?
Во-вторых: какой будет "своя" позиция при выводе числа от 0 до 99 со знаком, при условии выравнивания его по правой стороне?
По-моему, посчитать правую координату совсем не трудно. Во всяком случае проще, чем подбирать позицию в составной строке. Ну не мне тебе обьяснять, как выяснить, сколько разрядов в числе :)
Вот тут я и знак вывожу, и число разрядов после запятой меняю, чтобы все числа ровно в столбик вывести:
Зачем позицию подбирать? Или меня сегодня давлением придавило так, что я не совсем понимаю почему куча вычислений с расчётом позиции и кол-ва забивочных пробелов чтобы не получить " ++2C", будет экономней, чем:
Да и позиционирования-то у меня в функции, вобщем-то, нет - просто байстстриминг в I2C экспандер.
Да ладно, проехали : )Тебе так удобнее, а мне - эдак. Хотел картинкой похвастать :)
Так я без претензии. Моё знание не системное, порой даже какие-то простые штуки упускаю из виду. Поэтому и интересуюсь - может есть способ проще, экономней.