bug

M

MC felon

what's wrong with this??


#include <ofstream>
#include <iostream>

int main()
{
std::string str;
std::cout<<"Please enter a string\n";
getline(std::cin,str);
std::string savename;
std::cout<<"Please enter the name of the file to be saved as\n";
getline(std::cin,savename);
std::eek:fstream f(savename);
f << str;
return 0;
}


it's not working...
 
O

Ondra Holub

MC felon napsal:
what's wrong with this??


#include <ofstream>
#include <iostream>

int main()
{
std::string str;
std::cout<<"Please enter a string\n";
getline(std::cin,str);
std::string savename;
std::cout<<"Please enter the name of the file to be saved as\n";
getline(std::cin,savename);
std::eek:fstream f(savename);
f << str;
return 0;
}


it's not working...

1. There are missing error checkings
2. Slightly modified version which works (at least for good case
scenario) - changed is #include and opening of ofstream:

#include <fstream>
#include <iostream>

int main()
{
std::string str;
std::cout<<"Please enter a string\n";
getline(std::cin,str);
std::string savename;
std::cout<<"Please enter the name of the file to be saved as\n";
getline(std::cin,savename);
std::eek:fstream f(savename.c_str());
f << str;
return 0;

}
 
S

Salt_Peter

MC said:
what's wrong with this??


#include <ofstream>
#include said:
#include <iostream>

int main()
{
std::string str;
std::cout<<"Please enter a string\n";
getline(std::cin,str);

std::getline( std::cin, str );
std::string savename;
std::cout<<"Please enter the name of the file to be saved as\n";
getline(std::cin,savename);

std::getline( std::cin, savename );
std::eek:fstream f(savename);

std::eek:fstream ofs(savename.c_str());
if( !ofs.is_open() )
{
std::cerr << "error opening file\n";
return -1;
}
f << str;

ofs << str << std::endl;
return 0;
}


it's not working...

Without at least a rudimentary check, you are left in the dark.
An error-handling mechanism based on std::exceptions could come in
handy. It catches any std exception, not only those you throw.

#include <iostream>
#include <stdexcept>

int main()
{
try {
bool condition(false);
if( !condition )
{
throw std::runtime_error("condition failed");
}
}
catch( const std::exception& r_e )
{
std::cerr << "Error: ";
std::cerr << r_e.what() << std::endl;
}
}
 
D

Default User

std::eek:fstream ofs(savename.c_str());
if( !ofs.is_open() )
{
std::cerr << "error opening file\n";
return -1;
}

This is a non-standard return value from main(). It may or may not
cause problems for the operating environment.



Brian
 
S

Salt_Peter

Default said:
This is a non-standard return value from main(). It may or may not
cause problems for the operating environment.

How is that a non-standard return value? Its an integer, what the OS
does with it, if anything, is not C++'s concern. These are ignored by
most operating systems anyway.
What should not be optional, is not checking for any error and
returning or not providing some form of loop to recover. And as also
suggested, an exception mechanism is probably a better solution.
 
D

Default User

Salt_Peter said:
How is that a non-standard return value?

Because the standard doesn't specify what happens in that case. It's
implementation-defined behavior, for no particularly good reason. There
are three standard values to return: 0 and EXIT_SUCCESS signal
successful termination, while EXIT_FAILURE signals unsuccessful
termination. For best portability, those should be used.
What should not be optional, is not checking for any error and
returning or not providing some form of loop to recover.

Ok, no argument, but it doesn't really have anything to do with my
comment.




Brian
 
S

Salt_Peter

Default said:
Because the standard doesn't specify what happens in that case. It's
implementation-defined behavior, for no particularly good reason. There
are three standard values to return: 0 and EXIT_SUCCESS signal
successful termination, while EXIT_FAILURE signals unsuccessful
termination. For best portability, those should be used.

The standard has nothing to do with what the OS does with the return.
Whats nice, is seeing the returned non-zero integer when you are
debugging or developing.
Besides, macros should not be used in C++ to define constants. If you
really need the old-time C equivalent of those macros: then use a const
int definition for these, at least that way you'll get the appropriate
type-safety.

const int EXIT_SUCCESS(0);
const int EXIT_FAILURE(1);

These are not part of the language and an illusion since the OS gets
the integer anyways.
 
A

Alf P. Steinbach

* Salt_Peter:
The standard has nothing to do with what the OS does with the return
[from main].

The standard defines success and failure, nothing more.

Whats nice, is seeing the returned non-zero integer when you are
debugging or developing.
Besides, macros should not be used in C++ to define constants. If you
really need the old-time C equivalent of those macros: then use a const
int definition for these, at least that way you'll get the appropriate
type-safety.

const int EXIT_SUCCESS(0);
const int EXIT_FAILURE(1);

This ungood on four counts.

First, it's unnecessary: the standard library (specifically <cstddef>)
defines the names EXIT_SUCCESS and EXIT_FAILURE.

Second, it's invalid if you're using /any/ standard library header,
because you're redefining the names.

Third, you should generally reserve all uppercase names for macros, lest
you want to get into trouble.

Fourth, the value 1 is not guaranteed to denote failure on all OS-es.

These are not part of the language and an illusion since the OS gets
the integer anyways.

Sorry, parsing of the above sentence failed.
 
P

Pete Becker

Salt_Peter said:
Besides, macros should not be used in C++ to define constants. If you
really need the old-time C equivalent of those macros: then use a const
int definition for these, at least that way you'll get the appropriate
type-safety.

const int EXIT_SUCCESS(0);
const int EXIT_FAILURE(1);

This seems to be the received wisdom, but there's nothing in this that
isn't typesafe:

#define EXIT_SUCCESS 0

Wherever you use EXIT_SUCCESS its type is const int.

And, of course, since EXIT_SUCCESS and EXIT_FAILURE are provided by the
standard headers <stdlib.h> and <cstdlib>, you shouldn't be defining
your own things with those names.

And, finally, the reason for those manifest constants is that you can't
just return whatever value you want and expect every OS to make sense
out of it. Those constants will have the right values for the OS that
you're targetting. 0 and 1 might not (although if 0 doesn't mean
success, exit() will change it to a value that does).

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
D

Default User

Salt_Peter said:
The standard has nothing to do with what the OS does with the return.

That's not right. The standard dictates that EXIT_SUCCESS and 0 will be
a return that signals successful termination to the hosting
environment, regardless of what the actual values the implementation
needs. Similarly the EXIT_FAILURE macro must signal unsuccessful
termination.

The user doesn't have to be concerned with which values to return, the
implemenation has already taken care of that. If 1 is success and 0 is
failure, then the implementation will make sure that a return of 0 ends
up with the 1 the hosting evironment requires.

This aids portability, as one can then take the same code and move to
another platform with a different hosting environment, say one with 0
for success and -1 for failure, and have the code work without
modification.
Whats nice, is seeing the returned non-zero integer when you are
debugging or developing.

In all likelihood, EXIT_FAILURE is non-zero, but that's not that big of
a deal. Usually in debugging the exit value isn't all that important.
Besides, macros should not be used in C++ to define constants.

They should not be used by the USER. These are implementation macros.
If you
really need the old-time C equivalent of those macros: then use a
const int definition for these, at least that way you'll get the
appropriate type-safety.

Nonsensical. The implentation will take care of the type-safety
requirements.
const int EXIT_SUCCESS(0);
const int EXIT_FAILURE(1);

Beside illegally using system-defined things, you don't know what the
required termination code for unsuccessful exit is. That's where we
started. You don't know and should not be concerned, as that's an
implementation-specific detail. By trying to circumvent the
implementation, all you do is introduce non-portability.
These are not part of the language and an illusion since the OS gets
the integer anyways.

What aren't part of the language?




Brian
 
S

Salt_Peter

Default said:
That's not right. The standard dictates that EXIT_SUCCESS and 0 will be
a return that signals successful termination to the hosting
environment, regardless of what the actual values the implementation
needs. Similarly the EXIT_FAILURE macro must signal unsuccessful
termination.

The user doesn't have to be concerned with which values to return, the
implemenation has already taken care of that. If 1 is success and 0 is
failure, then the implementation will make sure that a return of 0 ends
up with the 1 the hosting evironment requires.

This aids portability, as one can then take the same code and move to
another platform with a different hosting environment, say one with 0
for success and -1 for failure, and have the code work without
modification.


In all likelihood, EXIT_FAILURE is non-zero, but that's not that big of
a deal. Usually in debugging the exit value isn't all that important.


They should not be used by the USER. These are implementation macros.


Nonsensical. The implentation will take care of the type-safety
requirements.


Beside illegally using system-defined things, you don't know what the
required termination code for unsuccessful exit is. That's where we
started. You don't know and should not be concerned, as that's an
implementation-specific detail. By trying to circumvent the
implementation, all you do is introduce non-portability.


What aren't part of the language?

Thanks for the input - i get the picture. I'ld rather be wrong and
corrected than completely clueless.
 
D

Default User

Salt_Peter wrote:

Thanks for the input - i get the picture. I'ld rather be wrong and
corrected than completely clueless.


What kind of attitude is that?


The goal wasn't to cause a battle, but really almost a reflexive post
from me due to time spent on comp.lang.c. That's a common issue there.

Hopefully, we all learned a bit.




Brian
 
S

Salt_Peter

Pete said:
This seems to be the received wisdom, but there's nothing in this that
isn't typesafe:

#define EXIT_SUCCESS 0

Wherever you use EXIT_SUCCESS its type is const int.

And, of course, since EXIT_SUCCESS and EXIT_FAILURE are provided by the
standard headers <stdlib.h> and <cstdlib>, you shouldn't be defining
your own things with those names.

And, finally, the reason for those manifest constants is that you can't
just return whatever value you want and expect every OS to make sense
out of it. Those constants will have the right values for the OS that
you're targetting. 0 and 1 might not (although if 0 doesn't mean
success, exit() will change it to a value that does).

Got it. And it makes sense.
 
D

Default User

Salt_Peter said:
No attitude above. In fact, you have my thanks.

That was attempting to be a joke, looks like if failed. I guess I
should have put a smiley in.



Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,430
Messages
2,571,676
Members
48,796
Latest member
Greg L.

Latest Threads

Top