Как я могу поймать ошибку форматирования из strftime в качестве исключения? - PullRequest
0 голосов
/ 08 июля 2020

Я использую ::strftime() в программе VS2013 на C ++. Есть ли способ правильно обработать ошибку "invalid format" без риска остановки всей программы?

Когда я запускаю код, подобный приведенной ниже функции, в неправильном формате, например "%Y- %- m-%d", это "ИГРА ЗАВЕРШЕНА ". Я получаю:

«Debug Assertion Failed ... Invalid format directive»

и могу остановить только приложение (набор модульных тестов).

Есть ли способ превратить это в исключение, код errno и т.д. c, чтобы я мог правильно справиться с этой ситуацией?

Или есть еще одна функция, которую я должен использовать?

Или я должен проверить строку формата вручную , прежде чем позвонить strftime()?

using namespace std;
string foo( string fmt ) // fmt: user supplied format - may be invalid
{
  if (fmt.empty()) return "";
  struct tm  myTm = ...; // get it some how
  size_t n = 0;
  size_t buflen = 2 * fmt.size();
  while (buflen < 100) {
    vector<char> buf( buflen, '\0' );
    try {
      n = ::strftime( buf.data(), buf.size(), fmt.c_str(), &myTm );
      if (n>0)
        return string( buf.data(), buf.data() + n );
      if ((n == 0) && (34 == errno)) {
        // 34 == "Result too large" (at least in VS2013)
        buflen *= 2; // try with larger buffer
        continue;
      }
      //   I NEVER REACH THIS POINT!  :-(
      throw runtime_error( "please check your format string!" );
    }
    catch (...) {
      //   I NEVER REACH THIS POINT!  :-(
      throw runtime_error( "please check your format string" );
    }
  }
  throw runtime_error( "max buffer size reached" );
}

1 Ответ

0 голосов
/ 08 июля 2020

В документации strftime() указано:

Эта функция проверяет свои параметры. Если strDest, format или timeptr является нулевым указателем, или если структура данных tm, адресованная timeptr, недопустима (например, если она содержит значения вне диапазона для времени или даты), или если строка формата содержит недопустимое форматирование код, вызывается обработчик недопустимого параметра, как описано в Проверка параметров . Если выполнение может быть продолжено, функция возвращает 0 и устанавливает для errno значение EINVAL.

В документации Parameter Validation указано:

Подпрограмма обработчика недопустимых параметров

Когда функция библиотеки времени выполнения C обнаруживает недопустимый параметр, она фиксирует некоторую информацию об ошибке, а затем вызывает макрос, который обертывает функцию отправки обработчика недопустимого параметра, одну из _invalid_parameter, _invalid_parameter_noinfo или _invalid_parameter_noinfo_noreturn. Вызываемая функция отправки зависит от того, является ли ваш код, соответственно, отладочной сборкой, розничной сборкой или ошибка не считается исправимой.

В отладочных сборках макрос недопустимого параметра обычно вызывает неудачное утверждение и точка останова отладчика перед вызовом функции отправки. Когда код выполняется, утверждение может быть передано пользователю в диалоговом окне, в котором есть «Прервать», «Повторить попытку» и «Продолжить» или аналогичные варианты выбора, в зависимости от операционной системы и версии библиотеки времени выполнения. Эти параметры позволяют пользователю немедленно завершить программу, подключить отладчик или позволить существующему коду продолжить работу, что вызывает функцию диспетчеризации.

Функция диспетчеризации обработчика недопустимых параметров, в свою очередь, вызывает назначенный в данный момент обработчик недопустимого параметра. По умолчанию недопустимый параметр вызывает _invoke_watson, что приводит к тому, что приложение выполняет «cra sh», то есть завершает работу и создает мини-дамп. Если это разрешено операционной системой, диалоговое окно спрашивает пользователя, хотят ли они загрузить дамп cra sh в Microsoft для анализа.

Это поведение можно изменить с помощью функций _set_invalid_parameter_handler или _set_thread_local_invalid_parameter_handler , чтобы установить обработчик недопустимого параметра для вашей собственной функции. Если указанная вами функция не завершает работу приложения, управление возвращается функции, которая получила недопустимые параметры. В CRT эти функции обычно прекращают выполнение функции, устанавливают в errno код ошибки и возвращают код ошибки. Во многих случаях значение errno и возвращаемое значение являются EINVAL, что указывает на недопустимый параметр. В некоторых случаях возвращается более конкретный код ошибки c, например EBADF для неверного указателя файла, переданного в качестве параметра. Для получения дополнительной информации об errno см. Errno, _doserrno, _sys_errlist и _sys_nerr.

...