From: Chris on
Here is a program that I wrote as an answer to one of the exercises
from "You Can Do It!" by Francis Glassborow:

#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>

#include "fgw_text.h"
#include "utilities.h"

using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::ifstream;
using std::sort;
using std::vector;

using namespace fgw;

int main() {
vector<int> numbers;
try {
ifstream source("wholeNumbers.txt");
if(source.fail()) {
cerr << "Failed to open wholeNumbers.txt" << endl;
throw problem("file failed to open wholeNumbers.txt.");
}
for(int finished = 0; finished != 1; ) {
int i(getint(source));
if (i == 0) {
finished = 1;
} else {
numbers.push_back(i);

}
}
}
catch(...) {
cerr << "***ERROR***" << endl;
}

sort(numbers.begin(), numbers.end());
int sum = 0;
for(int i(0); i != numbers.size(); ++i) {
cout << numbers[i] << endl;
sum = numbers[i] + sum;
}
int average = sum / numbers.size();
cout << "average: " << average << endl;

int numSize = numbers.size();
int mid = numSize/2;
int median = numSize % 2 == 0 ? (numbers[mid] + numbers[mid-1]) / 2 :
numbers[mid];
cout << "median: " << median << endl;
}

As you can see, the program opens a file, reads the data, and uses the
data to compute an average and a median. My question concerns the
try-catch block. In my solution, I use the block to surround the
portion of the code that opens the file and reads the information into
a vector. However, the solution provided by the book shows the
try-catch block enclosing the entire program. Which way is the correct
way?

From: Heinz Ozwirk on
"Chris" <cspears2002(a)yahoo.com> schrieb im Newsbeitrag news:1142883345.831924.325930(a)u72g2000cwu.googlegroups.com...
> Here is a program that I wrote as an answer to one of the exercises
> from "You Can Do It!" by Francis Glassborow:
....
> int main() {
> vector<int> numbers;
> try {
> ifstream source("wholeNumbers.txt");
> if(source.fail()) {
> cerr << "Failed to open wholeNumbers.txt" << endl;
> throw problem("file failed to open wholeNumbers.txt.");
> }
....
> }
> }
> }
> catch(...) {
> cerr << "***ERROR***" << endl;
> }
....
> int average = sum / numbers.size();
....
> As you can see, the program opens a file, reads the data, and uses the
> data to compute an average and a median. My question concerns the
> try-catch block. In my solution, I use the block to surround the
> portion of the code that opens the file and reads the information into
> a vector. However, the solution provided by the book shows the
> try-catch block enclosing the entire program. Which way is the correct
> way?

Give it a try. Change your program and try to open a file, that doesn't exist. How many elements will be in your vector and what will be their average? What will it print for 0/0?

It simply doesn't make sense to do anything with data you couldn't even read.

HTH
Heinz
From: Ulrich Eckhardt on
Chris wrote:
[summary of his program]
| open file
| read numbers into a vector
| sort vector
| output numbers
| compute sum
| compute average
| compute median

> As you can see, the program opens a file, reads the data, and uses the
> data to compute an average and a median. My question concerns the
> try-catch block. In my solution, I use the block to surround the
> portion of the code that opens the file and reads the information into
> a vector. However, the solution provided by the book shows the
> try-catch block enclosing the entire program. Which way is the correct
> way?

There is no correct way in this case. However, ask yourself something: what
if opening fails, where would you want to continue then? You probably
wouldn't want to read from a file which you failed to open in the first
place. You might perform some of the computations on an empty vector, but
how about the average, aren't you dividing by zero there?

Often, when you have dependent steps, you wrap them all in a try-catch
clause:

try
{
if(!fou())
throw std::runtime_error("fou");
if(!barre())
throw std::runtime_error("barre");
if(!baze())
throw std::runtime_error("baze");

std::cout << "success!\n";
}
catch(std::exception const& e)
{
std::cerr << "failure '" << e.what() << "'\n";
}

This gets even better when the three functions above throw exceptions
themselves, then you don't even have the error-checking obscuring the view
on what you really want to express.
Try putting the different steps of your program into functions that throw
exceptions when they encounter an unrecoverable error. You will see that
the main function will become as easy and clear to read as my above
summary of your program, except for the enclosing try-catch clause.

Uli

--
FAQ: http://ma.rtij.nl/acllc-c++.FAQ.html
From: Francis Glassborow on
In article <1142883345.831924.325930(a)u72g2000cwu.googlegroups.com>,
Chris <cspears2002(a)yahoo.com> writes
>int main() {
> vector<int> numbers;
> try {
> ifstream source("wholeNumbers.txt");
> if(source.fail()) {
> cerr << "Failed to open wholeNumbers.txt" << endl;
> throw problem("file failed to open wholeNumbers.txt.");
> }
> for(int finished = 0; finished != 1; ) {
> int i(getint(source));
> if (i == 0) {
> finished = 1;
> } else {
> numbers.push_back(i);
>
> }
> }
> }
> catch(...) {
> cerr << "***ERROR***" << endl;
> }
>
> sort(numbers.begin(), numbers.end());

I have limited the amount of your code that I quote so that I can focus
on the problem.

If you write the code as above, what happens if an exception is thrown
in the try block? It is caught by the catch, a suitable error message is
sent to std::cerr and then the program continues.

Read that last bit again. If you had an error somewhere in the try
block, why would it be correct to continue with sorting the elements of
the container? Something went wrong, at this stage in your programming
all you know is that something went wrong, and all you can do is to
print a message and stop. Try to understand that once a catch clause has
been executed the program will continue with the next statement (after
the last catch) so you better make sure that that is what you want to
do.




--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects