I want to make a program that will perform some math after reading from user input files.
During the reading process (a function) I want to check if the user syntax in the file is correct, otherwise I would like to shutdown the program so that the user can modify the file(s= accordingly and run it again.
The structure will be something like this:
int main(int argCount, char *args[])
{
std::string fileName = "PathOfFile";
int a = GetUserInput(fileName, variableName);
int b = GetUserInput(fileName, variableName);
// Other functions will be placed here
return 0;
}
int GetUserInput(std::string filename, std::string variableName)
{
// Some routine to read the file and find the variableName
// Some routine to check the syntax of the user input.
// Let us assume that the integers are to be fined as: variableName 1;
// and I want to check that the ; is there. Otherwise, shutdown the program.
}
How can I shutdown the program safely from the function GetUserInput
? Is there any C to signal that the program must wrap up and exit?
CodePudding user response:
There are many different ways of doing this, the differences are mostly style, personal preferences, and which parts of the C library you are familiar with.
- The parsing function simply calls
exit()
. - Instead of returning the
int
value setting, the function takes a pointer or a reference to anint
value as an additional parameter and sets it, if valid. The function returns abool
, instead, to indicate whether it parsed a valid setting.main()
checks the returnedbool
value, and itselfreturn
s frommain()
, ending the program. - The parsing function returns a
std::optional<int>
, instead, returning astd::nullopt
to indicate a parsing failure.main()
checks the returned value, and itselfreturn
s frommain()
, ending the program. - The parsing function throws an exception that gets caught in
main
, with the exception handlerreturn
ing frommain
.
Each alternative has its own advantages and disadvantages. You can decide, by yourself, which approach works best for your program.
CodePudding user response:
I would suggest to structure your code such that "normal shutdown" is return from main
. For example like this
bool GetUserInput(const std::string file,const std::string& variablename,int& a) {
a = ... read value from file...
if (something went wrong) return false;
return true;
}
int main() {
int a;
if (! GetUserInput("file","foo",a)) return 1;
int b;
if (! GetUserInput("file","foo",b)) return 1;
}
You can consider to throw an exception when something goes wrong:
void GetUserInput(const std::string file,const std::string& variablename,int& a) {
a = ... read value from file...
if (something went wrong) throw std::runtime_error("something went wrong");
}
int main() {
int a;
GetUserInput("file","foo",a);
int b;
GetUserInput("file","foo",b);
}
This allows you to catch the exception in main
and act accordingly in case you can recover from it. Also you can have different exceptions rater than only a single bool
.
If you merely want to exit the program cleanly, you can use std::exit
as suggested by πάντα ῥεῖ:
void GetUserInput(const std::string file,const std::string& variablename,int& a) {
a = ... read value from file...
if (something went wrong) std::exit();
}
This will safely shutdown your program (stack is unwound, ie destructors are called, files are closed properly, etc). However, this does not allow you to react on in the caller.