Число с ведущим нулем
- Войдите на сайт для отправки комментариев
Ср, 26/04/2017 - 16:58
Создаю проект на arduino с LCD 16x2 дисплеем. Так проблема в том что на него выводится время с часов реального времени и если число минут или часов является односимвольным например, от 1 до 9 происходит смещение и как следствие артефакты типа 7:599. Нашел, по моему мнению, костыль в виде
if(myRTC.hours<10 && myRTC.hours>0)
{
lcd.print("0");
lcd.print(myRTC.hours);
}
else
{
lcd.print(myRTC.hours);
}
Есть ли какие то более качественные способы вывода информации в виде 01, 02, 03.... 08 и 09?
А чем Вас этот не устраивает? Ну, можете printf воспользоваться, если склонны к "шалунизму" :)
Кстати, прикололо условие "&& myRTC.hours>0". А что, если время 0 часов, то лидирующий ноль не нужен?
Было на быструю руку скопированно из строки отображения даты по этому и >= не сделал. Спасибо за уточнение.
Вроде должно получится что то подобное, но компилятор возмущается. Либо я косячник либо библиотека не поддерживает
lcd.printf("%02d", myRTC.hours);Не должно. В библиотеке скорее всего нет такого меттода. Если хотите пользоваться, надо добавлять. Как добавлять - зависит о библиотеки, я не знаю какую Вы пользуете.
Но, вообще-то я пошутил. Нафига тащить в программу такого монстра, как printf ради бедного нуля? Делайте как у Вас сейчас.
По поводу проверки, Ваше исправление на ">=" тоже выглядит странным. Не может Ваш hour быть отрицательным ни при каких условиях, так что эту проверку надо просто убрать.
хватит тупить...
lcd.setCursor(0, 0); if (myRTC.hours < 10) {lcd.print('0');} lcd.print(myRTC.hours);Видел что применяли в своих проектах printf и показалось, что использование if является весьма обширной функцией. Благодарю за ответ.
Возможно я где то ошибаюсь, но если перевести в словесную форму условие то "часы больше, либо ровны 0" т.е. от 0 и до бесконечности.
Ну может быть так:
хватит тупить , уже все сделали до нас , ищем : printNumI()
String c2d (byte i){ // convert2digit - добавляю ноль перед числом до 10 и преобразовываю в строку String str = (String)i; if (i < 10) str = '0' + str; return str; }Oleg_Ru - ради двух символов заводить (пусть временно) два экземпляра класса String ?
А потом удивляемся. почему ппростенькой игрушке даже Меги не хватает
Это же функция, вызвали, выполнилось и все очистилось. Предложите другое однострочное решение, сам бы использовал. Написал это так как 1.Понятно выглядит 2. Закрыл вопрос с частым форматированием внутри кода.
пример из скетча:
пример из скетча:
Не понял, в Вашей библиотеке есть целый printf и Вы ещё к ней какое-то преобразование для добавления нуля колхозите?
Когда будете подвешивать к самолёту атомную бомбу, не забудьте засунуть её в мешок с гвоздями, чтобы увеличить поражающую способность.
Нет там printf, к сожалению. Описка...
объект software serial
про printf навеяли воспоминания про полноценную библиотеку stdio в "С" и тема с форума
http://arduino.ru/forum/programmirovanie/formatirovannyi-vyvod-v-serial
Вот здесь небольшая библиотечка. Просто включаешь и имеешь уже готовый потоковый вывод и полный printf в сериале.
("полный", но без плавающей точки только)
Это же функция, вызвали, выполнилось и все очистилось. Предложите другое однострочное решение,
А ваше решение "однострочное"? - что-то не заметил :)
void leading_zero(byte c, char* buf) { *(buf++)= '0' + c/10; *(buf++)='0' + c%10; *buf='\0'; } // Использование: byte i =3; char bb[3]; Serial.println(leading_zero(i,bb));Мое решение в 5 строк, ваше тоже. Про однострочное, это о том, что было бы действительно замечательно, если бы оно было.
Ваше решение возможно менее требовательное к памяти, надо попробовать.
В примере только должно быть так, наверное:
да, вы правы
а чо, принтф использовать запрещено?
String getTimeStr(RTC &Clock){ char *buf[8] = alloca(8); sprintf(buf, "%02d:%02d", Clock.getHours(), Clock.getMinutes()); return String(buf); }Мне вот всегда жалко полтора кило (или сколько там) ради какого-то сраного нуля. Я его как-нибудь и ручками туда запихаю
//принтф использовать запрещено?
Запрещено конечно. Она тяжеленная. А уж алокейтить память и не освобождать где алокейтил - очень жестко. Память начнет утекать 99%. Один процент оставлю для суперпеданта-профессионала делающего регулярный кодревю, ему даже можно оставить право на такой стиль. Лучше кода, чем от b707 не родить. разве что упростить для новичка
void leading_zero(byte c, char* buf) { buf[0]= '0' + c/10; buf[1]='0' + c%10; buf[2]='\0'; }Можно еще от выделения дробной части избавится типа tmp=c/10;..buf[1]='0' + c-tmp*10; Типа заменяем деление (это подпрограмма у 328р) на умножение (это одна команда), быстрей типа, но то уже для маньяков;)
А уж алокейтить память и не освобождать где алокейтил - очень жестко. Память начнет утекать 99%.
дак alloca сама освободится при выходе.
А String освободица при выходе из области её видимости. Подробностей точных не знаю, но подозреваю, что на уровне выше будет вызван копирующий конструктор, который у String очень грамотно и аккуратно написан, и возвращённый экземпляр тут же почит в бозе.
Хотя, да, смотря кто как это использует. Я пока такими граблями в лоп не огребал еще.
А String освободица при выходе из области её видимости. Подробностей точных не знаю, но подозреваю, что на уровне выше будет вызван копирующий конструктор, который у String очень грамотно и аккуратно написан, и возвращённый экземпляр тут же почит в бозе.
Ну да, после выхода все очистится. Но в сам момент выполнения функции будет создано аж два экземпляра String - каждый. если правильно помню - более чем по сотне байт в RAM. И все это ради строчки в 3 символа. А если этих 200 байт нет?
Короче, если можно обойтись без String - лучше обойтись
Дак а ТС за память ничо не говорил, ему бы покороче бы. :)
Дак а ТС за память ничо не говорил, ему бы покороче бы. :)
ТС потерял интерес к вопросу еще в 17м году :)
Нынешнее обсуждение началось с #8
аха, вот кто у нас некромант проклятый. :)
А чего некромант. Чел верно сделал, чем плодить кучу тем по одному вопросу намного лучше собирать все в одной.
А String освободица при выходе из области её видимости. Подробностей точных не знаю, но подозреваю, что на уровне выше будет вызван копирующий конструктор, который у String очень грамотно и аккуратно написан, и возвращённый экземпляр тут же почит в бозе.
Ну да, после выхода все очистится. ..
Ох уж эти сказки, ох уж эти сказочники )))
void setup() { // put your setup code here, to run once: Serial.begin(115200); } String getTimeStr(int i){ char *buf = malloc(8); sprintf(buf, "%02d", i); return String(buf); } void loop() { // put your main code here, to run repeatedly: // Использование: Serial.println(getTimeStr(millis())); delay(10); }Собралось длиней в 2,5 раза и ОЗУ больше.
Вывод дало:
как бы тебе памягше намекнуть, что malloc() от alloca() весьма существенно отличается?
Я заметил, с ним не собирается, потому и malloc(). Хотя конечно если не на куче выделять, а на стеке не все так плохо. Токо я его на ардуине чето не встречал.
дак #include <alloca.h> нада.
молотит уже 5 минут, как заводной, не вешаясь
Да, так молотит.
Запусти у себя: ;))))))))))))))))))
#include <alloca.h> void setup() { // put your setup code here, to run once: Serial.begin(57600); } String getTimeStr(int i){ char *buf = alloca(8); sprintf(buf, "%02d", i); return String(buf); } void loop() { uint16_t _SP = SP; char * tc = malloc(1); uint16_t _HP = (uint16_t) tc; free(tc); Serial.print(getTimeStr(millis())); Serial.print(" Memfree = "); Serial.println( _SP - _HP); delay(10); }век живи, век учися. :)
Дед! Это VSCode у тебя или прям студия целиком?
Студия. С темой BC 3.11
Я ж еще ГУИ на Шарпе изредка ваяю.
Я заметил, с ним не собирается, потому и malloc().
Жесть какая. С alloca() не собирается, поэтому заменил на malloc() не глядя, память при этом не освободил на выходе и сделал вывод, что чужие проэкты с багами. Прямо мегахит от второго по крутости (после Архата) программизда на форуме.
У вас тут точно отупин не разливали по стаканам?
А это просто modus vivendi. Персонаж всегда так себя ведёт. Все уже привыкли.
Насчёт.
тока прочитал, ржу не могу, форум юмористов мля :)))))