J'ai écrit une application simple qui lit un fichier de données, analyse le texte et effectue ensuite un traitement sur ces données. Le fichier de données est ouvert dans ma fonction main (). Est-ce une bonne pratique de programmation d'utiliser la fonction exit () s'il est déterminé que le fichier n'a pas été ouvert correctement? par exemple:
if (!file.is_open() ){
exit(1);
}
De plus, mon programme a une fonction distincte pour analyser les données du fichier. Cette fonction est appelée par main (). Si la fonction trouve une erreur dans les données, je veux que le programme s'arrête, après avoir imprimé un message d'erreur. Dans une telle situation, est-il acceptable d'utiliser la fonction exit () dans ma fonction d'analyse? Je pose cette question parce que, pour moi, il ne semble pas très bien de permettre à une fonction de quitter un programme de son propre chef sans retourner le contrôle à la fonction main (). (Je m'excuse si cette question semble assez évidente .. Je suis nouveau en C++ et en programmation en général).
Appeler exit
à partir d'une fonction n'est pas "mauvais" dans le sens où elle a un comportement bien défini - il n'y a rien de fondamentalement mauvais à le faire.
Mais, si vous écrivez une fonction qui pourrait se retrouver dans une bibliothèque par exemple, appeler exit
à partir de là est une mauvaise pratique en général: il est préférable de signaler une erreur au code appelant (via un valeur de retour ou exception par exemple) et laissez le code appelant décider quoi faire. (Il y a des cas où elle est parfaitement valide. Par exemple, si vous écrivez une fonction appelée quit_if_file_not_found
, eh bien, vos utilisateurs attendent une résiliation.)
Dans votre cas, votre fonction d'analyse ne devrait probablement pas appeler exit
: vous voudrez peut-être, par exemple, à un moment donné dans le futur, que votre code principal demande à l'utilisateur un nom de fichier différent s'il analyse le premier échoué. Si votre routine d'analyse met fin au programme, vous devez modifier à la fois votre code principal et cette fonction. S'il avait signalé une condition d'erreur, vous n'auriez qu'à modifier la logique dans main
.
(Et ne vous contentez pas de exit
sans imprimer un message d'erreur ou enregistrer quelque chose comme vous le faites ci-dessus, cela rendra les utilisateurs frustrés qui ne savent pas comment résoudre le problème rencontré par le code rencontré.)
Il y a deux aspects. L'un est l'intérêt de décider d'arrêter le programme à l'endroit où vous souhaitez utiliser exit
, l'autre est l'utilisation de exit. réponse de Mat couvre le premier.
Pour le second, exit
est généralement un mauvais choix en C++. La raison en est qu'il effectue un certain nettoyage (fonctions enregistrées avec atexit
et qui incluent parfois des destructeurs de certains objets de durée de stockage statique), mais pas tous (destructeurs d'objets sur la pile) et d'après mon expérience, vous soit vouloir tout ou rien.
exit(0)
indique la fin du programme et il est entièrement portable, tandis que
exit(1)
(généralement) indique une terminaison infructueuse. Cependant, son utilisation n'est pas portable.
De main
il n'y a pas de différence entre exit(1)
ou return 1
. Vous utilisez une valeur de retour/sortie de 0
pour le succès et non0
pour échec.
Si votre sous-routine est une routine de bibliothèque, qui est utilisée ailleurs, elle devrait retourner le contrôle à main avec du code retour ou une exception. Sinon, c'est votre choix, si vous exit
ou revenez.
Dans les deux cas, il est recommandé de documenter ce que fait la fonction, que ce soit exit
, return
code ou exception
.
Cela dépend d'où vient cette exit(1)
. Vous ne devez pas appeler cette exit(1)
à partir d'une bibliothèque, uniquement à partir de votre propre application.
Si vous devez définir un code d'erreur, vous pouvez définir un errno
(la variable STD C, oui).
Si vous souhaitez essayer une méthode plus C++, vous pouvez lever une exception, avec un code d'erreur détaillé.
La sortie est acceptable, bien que je pense qu'il est important de noter les différences dans la mémoire de l'utilisation de la sortie par rapport à une déclaration de retour dans cette sortie ne détruit pas les variables en mémoire. S'il y a une erreur, la sortie est justifiée. Sinon, je m'en tiendrai à la déclaration de retour.