У нас есть C++ / приложение MFC, которое позволяет пользователям настраивать форматирование даты через конфигурационные файлы. Не желая изобрести велосипед, я передаю строку формата CTime:: Формат (" <строка формата>"), чтобы сделать фактическое форматирование. Под покрытиями Формат называет вариант стандарта C функцией strftime ().
Естественно, пользователь может случайно ввести строку недопустимого формата. (Например, "%s" вместо "%S".), Когда это происходит, Время выполнения C называет Обработчик Недействительных аргументов, который, по умолчанию, выходит из приложения. (Никакие исключения для ловли - просто выход приложения.)
Мой вопрос состоит в том, как корректно обработать этот недоверяемый вход. В теории я мог записать свой собственный синтаксический анализатор/блок проверки допустимости для строки формата, но это походило на пустую трату времени. Вместо этого лучшее, которое я мог придумать, должно было установить мой собственный (глобальный) обработчик недействительных аргументов, который, вместо выхода, выдает исключение Недействительного аргумента:
void MyInvalidParameterHandler(
const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved)
{
::AfxThrowInvalidArgException();
}
Это, действительно кажется, работает и позволяет моему явно ловить (и корректно обрабатывать) исключения недействительного аргумента в случаях, где я "ожидаю", что они произойдут. Я обеспокоен, однако, что переопределяю глобальную, установку во время выполнения в крупном приложении для решения относительно "локальной" проблемы - я не хотел бы в эту фиксацию вызвать дополнительные проблемы в другом месте.
Действительно ли этот подход разумен? Или есть ли более чистый подход, решая эту проблему?
Если вас интересует только эта ошибка в определенное время вы можете временно заменить обработчик недопустимого параметра, а затем вернуть его обратно после вызова Format.
_invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(MyInvalidParameterHandler);
// Your try/Format/catch code here
_set_invalid_parameter_handler(oldHandler);
Конечно, я полагаю, что если у вас есть несколько потоков в вашей программе, другой поток может в конечном итоге вызвать ваш обработчик недопустимых параметров, пока он установлен. Вам нужно будет определить, насколько это вероятно.
Я не знаю, как еще можно это сделать, кроме написания собственной функции проверки.