1

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?

Manuel Oliveira
  • 527
  • 5
  • 19
  • 2
    Calling `exit()` is for that purpose. But that's OS dependent. – πάντα ῥεῖ Sep 25 '21 at 13:03
  • So if there is any syntax error, I can just call `std::exit(EXIT_FAILURE)` and it will be good? The OS I am using is Ubuntu 18.04 – Manuel Oliveira Sep 25 '21 at 13:08
  • 2
    If `GetUserInput` can't be completed due to bad user input, it should throw an exception. Then, you can catch that exception and handle the problem wherever or however you want. In your case, you can catch in main and cleanly return. Later, you might come up with a better strategy, like a retry loop. Exiting from a function is usually not a good idea, it is surprising and prevents anyone from doing anything about the error. – François Andrieux Sep 25 '21 at 13:09
  • *"shutdown the program safely"* -- Is this merely hypothetical, or is there a particular cleanup task that you are concerned about? What would you say is unsafe about abruptly terminating the program? *(The point here is to make sure that any proposed solution will cover your particular case. You might have a concern that others would not think of.)* – JaMiT Sep 25 '21 at 15:32

2 Answers2

4

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.

  1. The parsing function simply calls exit().
  2. Instead of returning the int value setting, the function takes a pointer or a reference to an int value as an additional parameter and sets it, if valid. The function returns a bool, instead, to indicate whether it parsed a valid setting. main() checks the returned bool value, and itself returns from main(), ending the program.
  3. The parsing function returns a std::optional<int>, instead, returning a std::nullopt to indicate a parsing failure. main() checks the returned value, and itself returns from main(), ending the program.
  4. The parsing function throws an exception that gets caught in main, with the exception handler returning from main.

Each alternative has its own advantages and disadvantages. You can decide, by yourself, which approach works best for your program.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • I want the program to shutdown if the user input is bad. Afterwards, there will be several math calculations and creation several objects. So, I think I will opt for the the call of `exit()` with a text message saying where the input has problems (line of the file with syntax problems). If the user reruns the script will the use of `exit()` have any potential issues? – Manuel Oliveira Sep 25 '21 at 13:25
  • Mere use of `exit()` alone has no intrinsic "issues". It does what it does. It all depends on how the rest of your program works, that determines whether or not using `exit()` will have any undesirable results. If, for example, your program writes files, and `exit` gets called in the middle of it, the files will be incomplete. Whether that is an issue, or not, is, again, dependent entirely on how the program works. Nobody will be able to tell you if using `exit` in your program will have "issues", only you have the source to your entire program, and can make that determination. – Sam Varshavchik Sep 25 '21 at 13:27
  • It will not write, but it will read. Will `exit()` close the file? Or do I have to close it first and then exit the program – Manuel Oliveira Sep 25 '21 at 13:29
  • Depends on how the file is opened before `exit()` is called. C++ objects of automatic storage duration are not destructed - including iostreams and destruction of those objects manages flushing (of any buffered output for output streams) and closing. Objects of static storage or thread-local storage are destructed (in reverse order of their creation) and that goes for streams too. C streams are flushed and closed. Practically, incomplete closure of an input file is usually not problematical, but files opened for writing or update may be. – Peter Sep 25 '21 at 13:59
  • All modern operating systems will release all resources, and close any files that are left open by a process when it exits. This is your operating system's job, that's what it's designed for. – Sam Varshavchik Sep 25 '21 at 22:41
1

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.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185