метод класса параметров по умолчанию

У меня есть эта функция (которая отлично работает):

String Esper::rtcTimeString() {
  DateTime now = rtc.now();
  char buf[] = "MM/DD/YY hh:mm:ss";
  return now.toString(buf);
}

Я хотел бы иметь значение по умолчанию "ММ/ДД/ГГ чч:мм:сс", но также передать аргумент параметру, например "ММ/ДД/ГГГГ", если я хочу переопределить это поведение по умолчанию .

Обычно в файле определений .h я делаю что-то вроде:

String rtcTimeString(char ts[] = "MM/DD/YY hh:mm:ss");

и впоследствии в .cpp:

String Esper::rtcTimeString(char ts[]) {
  DateTime now = rtc.now();
  return now.toString(ts);
}

Однако в результате каждый раз возвращается одна и та же строка времени.

например

1/6/2020 12:01:12
1/6/2020 12:01:12
1/6/2020 12:01:12

Как мне реализовать параметр, чтобы функциональность была такой же, как в первом блоке кода?

, 👍0

Обсуждение

Я ожидал, что char ts[] будет передан в качестве ссылки (вы можете изменить аргумент на char*, но я сомневаюсь, что это улучшится... Я предлагаю использовать компилятор для ПК (например, бесплатную Visual Studio 2019 C++) и использовать внутренний отладчик, чтобы увидеть, что на самом деле передается и где именно идет не так, а затем перенести исправленный код обратно в Arduino., @Michel Keijzers


2 ответа


Лучший ответ:

1

Вы не можете передать массив символов в качестве аргумента (неявного или нет) к функции. Когда вы пишете

String rtcTimeString(char ts[] = "MM/DD/YY hh:mm:ss");

Обозначение массива неявно преобразуется в указатель. Строка выше тогда эквивалентно:

String rtcTimeString(char *ts = "MM/DD/YY hh:mm:ss");

И это неверно: вы инициализируете указатель на модифицируемый символов, используя адрес массива постоянных символов. компилятор должен был предупредить вас об этом... если вы включили компилятор предупреждения. Правильный прототип должен быть

string rtcTimeString(const char* ts = "MM/DD/YY hh:mm:ss");

Но тогда вы не сможете передать этот указатель в DateTime::toString(), так как это метод ожидает, что строка шаблона будет жить в буфере, который она может перезаписать: туда будет записана отформатированная строка.

Я предлагаю следующее решение:

string rtcTimeString(const char* ts = "MM/DD/YY hh:mm:ss") {
    DateTime now = rtc.now();
    char buf[strlen(ts)+1];  // выделить новый буфер
    strcpy(buf, ts);         // копируем туда шаблон
    return now.toString(buf);
}
,

Хорошо объяснил. Спасибо!, @Alex


1

Это базовый C++ (и GIYF).

Как насчет

String Esper::rtcTimeString(std::string dateTimeForamt = "MM/DD/YY hh:mm:ss")
{
  DateTime now = rtc.now();

  return now.toString(dateTimeForamt );
}

См., например, этот вопрос. Надеюсь, это поможет :-)

,