Nous avons une application C++/MFC qui permet aux utilisateurs de personnaliser la mise en forme de la date via des fichiers de configuration. Ne voulant pas réinventer la roue, je passe la chaîne de format à CTime :: Format ("< chaîne de format>") pour faire le formatage réel. Sous les couvertures, Format appelle une variante de la fonction C standard strftime().Appel sécurisé de strftime avec une chaîne de format non fiable
Naturellement, l'utilisateur peut entrer accidentellement une chaîne de format invalide. (Par exemple, "% s" au lieu de "% S".) Lorsque cela se produit, C Run-Time appelle le Invalid Argument Handler qui, par défaut, quitte l'application. (Aucune exception à attraper - juste une sortie d'application.)
Ma question est comment gérer avec élégance cette entrée non fiable. En théorie, je pouvais écrire mon propre analyseur/validateur pour la chaîne de format, mais cela ressemblait à une perte de temps. Au lieu de cela, le mieux que je pouvais trouver était de mettre mon propre (global) gestionnaire d'argument non valide qui, au lieu de sortir, renvoie une exception Argument non valide:
void MyInvalidParameterHandler(
const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved)
{
::AfxThrowInvalidArgException();
}
Cela ne semble pas fonctionner, et permet à mon explicitement attraper (et gérer gracieusement) les exceptions d'arguments invalides dans les cas où je "m'attends" à ce qu'elles se produisent. Cependant, je suis préoccupé par le fait que je remplace un paramètre global d'exécution dans une grande application afin de résoudre un problème relativement «local» - Je détesterais que cette correction provoque des problèmes supplémentaires ailleurs.
Cette approche est-elle sensée? Ou y a-t-il une approche plus propre pour résoudre ce problème?
Nous vous remercions de votre suggestion. Malheureusement, mon application est en fait multi-threadée, donc je ne pense pas que je peux basculer en toute sécurité le gestionnaire d'avant en arrière. (Le gestionnaire de paramètre invalide est global, plutôt que spécifique au thread.) –
Dans ce cas, je crois que vous devrez créer votre propre fonction de validation. Ça ne devrait pas être si difficile. Si vous regardez dans strftime.c dans le code source CRT, vous verrez une fonction appelée _expandtime. Il contient une instruction case pour tous les spécificateurs de format pris en charge. Vous pouvez l'utiliser comme base pour votre fonction. – Dustin
Une possibilité consiste à ajouter votre propre gestionnaire de paramètres invalide qui ne fait rien. Les docs indiquent que si le contrôle retourne à la fonction appelante, il retournera un code d'erreur. – Dustin