argv is a vector of char *, right so, you want argv[1] for example.
--
Mats
argv is a vector of char *, right so, you want argv[1] for example.
--
Mats
Good. I was confused earlier because I assumed when you overflow the int atoi just left it as the largest possible value, which was obviously an incorrect assumption.
Yeah that makes sense. I corrected the code and it's all working perfectly now, if i input something like "main.exe 23498723598724985729857", strtol() sets n to LONG_MAX and new overflows, so i get the overflow error and the program exits correctly
Thanks alot matsp and Daved, great help!
By the way, why would anyone use atoi() when strtol() does the same AND checks for overflow?
Edit: Oh, and one last question, would it be better if i didn't use std::nothrow and used the exceptions correctly, does it matter in a small program like this?
Last edited by Neo1; 08-09-2007 at 05:34 PM.
I think the reason atoi exists at all is that it was created (a long time) before strtol().
As I described, you can actually check if the number overflowed by looking at "errno" after strtol() - not that it REALLY makes much difference if someone entered some huge number...
--
Mats
If you add using namespace std; after your #includes you don't need to prepend std:: all over the place.Oh, and how is my program style-wise
You could use std::auto_ptr or some other smart pointer to prevent memory leaks. i.e.:
Then you'd have to remove your own delete [] code since the auto_ptr will delete it for you.Code:auto_ptr<int> Input_ptr( new (std::nothrow) int[n] ); // instead of: Input_ptr = new (std::nothrow) int[n];
Get rid of all those nasty C-functions and use std::stringstream:
Code:stringstream str; str << argv[1]; unsigned int n = 0; str >> n; if ( str.fail() == true ) { cout << "Error converting argv[1] to unsigned int!" << endl; }Not exactly. It's an array of char*Originally Posted by matsp
argv is a vector of char *, right so, you want argv[1] for example.
This will make a programming style worse not betterIf you add using namespace std
All problems in computer science can be solved by another level of indirection,
except for the problem of too many layers of indirection.
– David J. Wheeler
Bad. What if n is negative? The loop condition will be false and you will then attempt to allocate a negative number of objects on the heap. Bad things could happen.Code:/* Check to see whether or not the first parameter is a number greater than 0 */ if(!n)
If you want to "Check to see whether or not the first parameter is a number greater than 0" then do just that.
If you put it in a header file or before an #include you are right, but other than that it's perfectly fine.vart: This will make a programming style worse not better
I'm gonna have to disagree with you on that one, when using namespace std; you bring each name and symbol from the std namespace into scope, so if i use a name for a function or variable that is in the std namespace, without me knowing it, it might lead to some clashes. I thought a bit about using "using std::cin" and "using std::cout" but i just think my code looks alot prettier the way it is now...
Last edited by Neo1; 08-12-2007 at 12:27 PM.
As the doctor says, "Then don't do that."
If "using namespace" was universally bad, it would not have been put in the language. When I use it, I tend to use it within a function scope, not module scope:
Keeping it at the function level makes it easier to apprehend all the names which might be used and therefore makes clashes much less likely.Code:void some_function() { using namespace std; ... }
At any rate, reusing a name from std:: is a bad idea. Namespaces weren't invented to be a pain in the ass, making you type std:: everywhere. They were invented to help avoid name clashes between external libraries. In my opinion, std:: should not have been created in the first place -- it all should have gone into the global namespace.
I never said it was universally bad did i? Correct me if i'm wrong but i believe that the reason it was put in the language is so that you don't have to type out std:: all over the place when recompiling legacy code. Why put a bunch of functions into the scope if you're only going to be using maybe 5 or 6 of them anyways, imho, if you're going to be "using" anything, only do it with the stuff that you're actually planning on putting in your code, like "using std::string" and "using std::swap" and so on.
It will only clash with names that you #include. If you only #include <iostream> and decide to use variables named 'string' (a bad idea since you might decide to use STL strings in the future) then there won't be any problems.
If you do have name conflicts (extremely unlikely in my experience) then you have two choices:
- Rename your variable or function to something else.
- Explicitly specify the namespace that the name belongs to (std:: or whatever:: )