• 0

[C++] Close All Open Streams


Question

Is there a way in C++ to close all open streams without directly referencing the stream:

e.g. filestream.close();

I ask because I have a program where one of my file streams in not in scope when I call exit(-1) to terminate my program. The file stream is a member of a class and I would like to avoid having to pass around another reference to the class. Anyway to do something like:

cin:streams.close();

???

Lastly, does it even matter if I close it, or will it get closed by destructors when I call exit(-1)? Thanks

Link to comment
Share on other sites

9 answers to this question

Recommended Posts

  • 0

If you're using gcc or STLport, it is automatically closed. From the gcc-3.4.5 (MinGW) header:

	  /**
	   *  @brief  The destructor closes the file first.
	  */
	  virtual
	  ~basic_filebuf()
	  { this->close(); }

You might look into your header files to determine the answer. That was found in the fstream header, so the code for the destructor might be in the same header.

Link to comment
Share on other sites

  • 0
If you're using gcc or STLport, it is automatically closed. From the gcc-3.4.5 (MinGW) header:

	  /**
	   *  @brief  The destructor closes the file first.
	  */
	  virtual
	  ~basic_filebuf()
	  { this->close(); }

You might look into your header files to determine the answer. That was found in the fstream header, so the code for the destructor might be in the same header.

But a destructor gets called when you either delete or go out of scope. Calling exit() does neither, it bypasses any C++ exit code that gets run when your program (main()) goes out of scope.

You can try it with the following code:

#include <stdlib.h>

#include <iostream>

class MyTest {
public:
	MyTest() { std::cout << "Constructor" << std::endl; }
	~MyTest() { std::cout << "Destructor" << std::endl; }
};

int main() {
	MyTest test;

	exit(-1);

	return 0;
}

First run without the exit(-1), then with and you'll see the difference. Basically, don't use exit() in C++.

Link to comment
Share on other sites

  • 0

If I don't use exit(-1) to kill the program, is there some safer alternative that won't require exceptions or passing around a lot of extra variables?

Here's what I'm trying to do:

//Generic error message thrower and application exiter
void stopWithError(string s)
{
	cout << "ERROR: " << s << endl << "Terminating Parser.";
	Tokenizer *t = Tokenizer::Instance();  //Instance returns a Singleton, so this is good
	t->closeInput();
	//I have a ParseTree class that also has closeInput() function
	//, however, it doesn't use the Singleton
	//pattern, so I can't easily get a reference to the ParseTree class
	// -- and I call this function
	//from many different places.
	//I want to be able to do these 2 lines as well, but am not sure how to w/o passing
	//the parsetree object around all the time.  Is there any other way?
	//	 parsetree->closeInput();
	//	 delete parsetree;
	exit(1);
}

Link to comment
Share on other sites

  • 0

You could make it so that each instance of your class adds an instance of the stream to a static vector. You could then add a static function that loops through the vector and closes everything.

Using a setjmp/longjmp back to main() (so that you could return and run all the destructors) would probably be an option as well.

Link to comment
Share on other sites

  • 0
You could make it so that each instance of your class adds an instance of the stream to a static vector. You could then add a static function that loops through the vector and closes everything.

I was thinking the same thing. Have a singleton with a factory method to allocate your streams and keep track of them, and a have a closeAll to close all your streams or a close method to close individual ones.

As for using setjmp/longjmp, avoid it for the same reason as exit(). You'll bypass destructors that get called when your functions go out of scope.

OP: Are you by any chance writing a compiler (I am)? If so, you could probably restructure your code to avoid all this hassle. Also, if you're catching and report errors in parsing and then quitting, it's better to try and recover from parsing errors than just quitting.

Link to comment
Share on other sites

  • 0

Thanks for the static vector idea - I'll probably go with that due to my class deadline.

I am in fact writing an interpreter (not a compiler) for a made up language (oh boy). I'm very interested in the code restructuring idea. Can you explain what the general idea would be? Also, what are some general techniques for recovering from parsing errors without quitting? Do you have to be looser with your language grammar? Thanks.

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.