#include <iostream>
int main()
{
int num = 1;
try
{
if (num != 0)
{
throw "num is not 0!";
}
}
catch (char *x)
{
cout << x << endl;
}
}
I want this code to print "num is not 0!" to cout but when i run it i get libc++abi.dylib: terminating with uncaught exception of type char const*
Abort trap: 6 as output from the terminal. Am I misunderstanding how exceptions work or is there some other problem?
This is because you throw a string literal and it cannot be bound to char*. Rather it can be bound to char const*.
Pedantically, the type of "num is not 0!" is char const[14], however, in throw expression the array decays to a pointer to its first element.
Related
Program in c++.
My goal for this assignment is to make sure the user enter only one argument in command line and that argument has to contain digits only and greater than 3. Otherwise, print error.
For example:
$ ./a.out 4
Successful!
$ ./a.out abc
Must be a numeric string grater than 3
$ ./a.out 4 abc
Must be one argument only
$ ./a.out 2
Must be a numeric string greater than 3
$ ./a.out 2ab
Must be a numeric string
This is my code so far to handle accepting one argument and greater than 3. I don't know to handle the numeric string part.
int main(int argc, char **argv){
if (argc == 2){
int num = atoi(argv[1];
if (num >3){
cout << "Successful" << endl;
else{
cout <<"Must be a numeric string greater than 3"<< endl;
}
else{
cout << "Must be one argument" << endl;
}
return 0;
}
I have tried this and got segmentation error.
int main(int argv, char **argv){
if (argc == 2){
int num = atoi(argv[1];
int i;
if (num >=3 && isdigit(argv[1][i]){
cout << "Successful" << endl;
else{
cout << "Must be a numeric string greater than 3"<<endl;
}
else{
cout << "Must be one argument" << endl;
}
return 0;
}
You could use std::strtol instead of atoi; this way you can check that the parsing stopped at the end of that string.
here is code that compiles and does not crash but doesn't produce the right answer. It doesn't work because you are only looking at the first char of argv[1]. Why did it crash, becuase you indexed using i which was untitialized
#include <iostream>
#include<ctype.h>
int main(int argc, char** argv) {
if (argc == 2) {
int num = atoi(argv[1]);
int i = 0;// <<<<========================================
if (num >= 3 && isdigit(argv[1][i])) {
std::cout << "Successful" << std::endl;
}
else {
std::cout << "Invalid" << std::endl;
}
}
else {
std::cout << "Must be one argument" << std::endl;
}
return 0;
}
to make it do the right thing you need to loop over all argv and inside that loop you must loop over all chars in argv[i]
note that I removed the using namespace - see here Why is "using namespace std;" considered bad practice?
Your text and your code are at odds with each other. Is 3 acceptable or not? My code below assumes it is not based on what you wrote.
The big thing here is that atoi() lacks the ability to tell you if the whole string was processed or not. You want to use what C++ provides from <string>, std::stoi() or the long or long long variations depending on what you expect a reasonable range of inputs to be.
std::stoi() has a second output parameter that tells you how many characters were processed. What you then need to check is if the number of characters processed is the length of the string. If not, some non-numeric charcters were entered.
Example code below.
#include <cstring>
#include <iostream>
#include <string>
int main(int argc, char* argv[]) {
if (argc != 2) {
std::cerr << "USAGE: ./a.out ARG\n";
return 1;
}
std::size_t loc;
int val;
// The try block is necessary because std::stoi() throws if the resulting
// number cannot be contained in the type, and if processing fails on the
// first character.
try {
val = std::stoi(argv[1], &loc);
} catch (...) {
std::cerr << "INVALID PARAMETER\n";
return 2;
}
if (loc != std::strlen(argv[1])) {
std::cerr << "INPUT MUST BE FULLY NUMERIC\n";
return 3;
}
if (val <= 3) {
std::cerr << "Parameter must be > 3\n";
return 4;
}
std::cout << "Parameter: " << val << '\n';
}
Test runs:
~/tmp
❯ ./a.out
USAGE: ./a.out ARG
~/tmp
❯ ./a.out 1
Parameter must be > 3
~/tmp
❯ ./a.out 4
Parameter: 4
~/tmp
❯ ./a.out 2ab
INPUT MUST BE FULLY NUMERIC
~/tmp
❯ ./a.out ab
INVALID PARAMETER
Other answers are good and correct. My goto for stuff like this is to use a stringstream.
#include <optional>
#include <sstream>
#include <string>
template <typename T>
auto string_to( const std::string & s )
{
T value;
return (std::istringstream( s ) >> value >> std::ws).eof()
? value
: std::optional <T> {};
}
It is easy enough to use:
#include <iostream>
int error( const char * message )
{
std::cerr << message << "\n";
return 1;
}
int main( int argc, char ** argv )
{
if (argc != 2) return error( "Must be one argument only" );
auto n = string_to<int>( argv[1] );
if (!n) return error( "Must be a numeric string" );
if (n <= 3) then error( "Must be a numeric string grater than 3" );
std::cout << "Successful!\n";
}
The basic principle behind all these answers is you must try to convert it to an integer to see if it is, in fact, an integer.
I like my little utility function (string_to<type>()) because it does all the dirty work correctly: it attempts to convert the value, meaning there may be whitespace before the value but nothing else. It then reads any remaining whitespace and checks for EOF (meaning nothing but whitespace may follow the value). Only if all the checks pass do you get a value back.
I like std::optional because it is exactly for these kinds of things — either you have a value or you do not. You could throw instead, or return a default value, or whatever works. Heck, you could inline it in your main function:
int main(...)
{
...
int value;
if (!(std::istringstream( argv[1] ) >> value >> std::ws).eof())
error( ... );
That’s ugly though, and not very descriptive. I prefer to put things in little helper functions (which the compiler may very well inline) with nice, descriptive names. Like that error function I used there: it tells you exactly what is going on just by reading the code.
I'm trying to throw an exception in my code if a vector that is created from user input is not sorted in either descending or ascending order.
using namespace std;
#include <iostream>
#include <vector>
#include <algorithm>
int main () {
vector <int> vec;
//Let user fill a vector with 12 integers.
//cout << "Please note that input data should be either increasing or decreasing." << endl;
int n = 0;
int size = 0;
while(size < 12) {
cout << "Type integer to add to the vector." << endl;
cin >> n;
vec.push_back(n);
++size;
}
//throw exception if unsorted
try {
if (!((is_sorted(vec.begin(), vec.end())) || (is_sorted(vec.end(), vec.begin())))) {
throw "Input was not sorted.";
}
}
catch(exception &error){
cerr << "Error: " << error.what() << endl;
}
}
I have not included the rest of the code, which searches for a particular number, because I am pretty sure that it is irrelevant to this issue. When the data filled into the vector is ascending or descending, everything is fine, but when I test the exception, I get, "terminate called after throwing an instance of 'char const*' Aborted" instead of my desired error message. I don't understand what is going on here. Is it something wrong with the way I'm handling exceptions or am I using the sort() function incorrectly?
In C++, all types are throwable and catchable, but you are only catching subclasses of std::exception.
The best fix to your code would be changing your throw statement to:
throw std::runtime_error("Input was not sorted.");
If you want to catch an exception, you should throw an exception, not a const char*.
See this answer: c++ exception : throwing std::string
You're throwing a const char* not an std::exception. So catch it as a const char*:
catch(const char* error) {
std::cout << "Error: " << error << "\n";
}
Or throw an std::exception.
Remember that you can throw many types and have many catch blocks, the one that will be invoked is the one that matches the type of the thrown exception.
I am trying to catch bad allocation error. When input length will be in order of 10000000000000000000000 or something, then bad allocation error should come. I don't know why its not being caught.
Any help will be appreciated!
# include <vector>
# include <iostream>
using namespace std;
void length(int m)
{
vector<int> x;
try
{
x.resize(m);
}
catch(std::bad_alloc&)
{
cout << "caught bad alloc exception" << std::endl;
}
}
int main()
{
int l;
cout << "Length" ;
cin >> l ;
length(l);
return 0;
}
UPDATED:
When I am hard coding the value for input, then it is throwing an exception. I don't know why its working this way.
# include <vector>
# include <iostream>
using namespace std;
void length(int m)
{
vector<int> x;
try
{
x.resize(m);
}
catch(std::bad_alloc&)
{
cout << "caught bad alloc exception" << std::endl;
}
}
int main()
{
int m= 100000000000000000000;
length(m);
return 0;
}
You ought to write
if (!(cin >> l)){
// I could not read that into `l`
}
The lack of an exception being caught could be down to
Your int value being smaller than you think (perhaps some undefined wrap-around behaviour), and an exception is not thrown since the allocation is successful.
The allocation being lazy in the sense that the memory is not allocated until you actually use it.
If std::bad_alloc is thrown as an anonymous temporary then it will not be caught at your catch site. (Unless your naughty compiler allows non-const references to bind to anonymous temporaries, which some do as an extension). Write catch (const std::bad_alloc&) instead, and it will be caught there.
The maximum length of an integer type int is 2.147.483.647 . Are you sure you have actually used an higher number to test it?
You're passing Integer variable which has the limit.
Minimum value for a variable of type short: –32768
Maximum value for a variable of type short: 32767
The error which you will get from your code is std::length_error
To raise the bad allocation error dynamically you can try malloc() with incorrect size OR try below code.
#include <iostream>
#include <new>
int main()
{
try {
while (true) {
new int[100000000ul];
}
} catch (const std::bad_alloc& e) {
std::cout << "Allocation failed: " << e.what() << '\n';
}
}
</i>
No exception is thrown because the int that makes it through to your function void length(int m) is capped at its max value that is much less than vector::max_size(). Consider:
void length(int m)
{
cout << "m is: " << m << " which has a max value: " << numeric_limits<int>::max() << endl;
// ...
}
with the output:
Length10000000000000000000000
m is: 2147483647 and has a max value: 2147483647
In C++, I'm trying to write a function with function pointers. I want to be able to throw an exception if a function pointer is passed for a function that does not exist. I tried to handle the function pointer like a normal pointer and check if it is null
#include <cstddef>
#include <iostream>
using namespace std;
int add_1(const int& x) {
return x + 1;
}
int foo(const int& x, int (*funcPtr)(const int& x)) {
if (funcPtr != NULL) {
return funcPtr(x);
} else {
throw "not a valid function pointer";
}
}
int main(int argc, char** argv) {
try {
int x = 5;
cout << "add_1 result is " << add_1(x) << endl;
cout << "foo add_1 result is " << foo(x, add_1) << endl;
cout << "foo add_2 result is " << foo(x, add_2) << endl; //should produce an error
}
catch (const char* strException) {
cerr << "Error: " << strException << endl;
}
catch (...) {
cerr << "We caught an exception of an undetermined type" << endl;
}
return 0;
}
but that doesn't seem to work. What is the best way to do this?
Checking for NULL is ok. But it is not possible to pass a pointer to a function that does not exist in the first place. So you don't have to worry about this. Although it is possible to just declare a function without defining it and pass the address of it. In that case you will get linker error.
It will automatically throw an error if you are passing pointer which does not exist, if you are declaring a pointer then you have to initialize it with null to avoid garbage value, so comparing with null will not serve any purpose.
you still you want to check then try to assign some function(like add, sub etc.), if it takes then ok , if not then it will show again error as previously mentioned.
#include<cstddef>
#include <iostream>
using namespace std;
int foo(const int& x, int (*funcPtr)(const int& x)) {
if (*funcPtr != NULL) {
return funcPtr(x);
}
else
{
cout << "not a valid function pointer";
}
}
If you want to 'throw' exception then you need to 'catch' it as well.
Your code is failing because of two reasons in short,
1) You are not checking value of function pointer.
2) You are not properly catching the thrown exception.
My OS is Win8
using Code::Blocks 12.10
I'm trying to get a handle on throwing and handling exceptions using an example from
Starting Out with C++ Early Objects Addison Wesley.
Here is the simple code I'm using:
// This program illustrates exception handling
#include <iostream>
#include <cstdlib>
using namespace std;
// Function prototype
double divide(double, double);
int main()
{
int num1, num2;
double quotient;
//cout << "Enter two integers: ";
//cin >> num1 >> num2;
num1 = 3;
num2 = 0;
try
{
quotient = divide(num1,num2);
cout << "The quotient is " << quotient << endl;
}
catch (char *exceptionString)
{
cout << exceptionString;
exit(EXIT_FAILURE); // Added to provide a termination.
}
cout << "End of program." << endl;
return 0;
}
double divide(double numerator, double denominator)
{
if (denominator == 0)
throw "Error: Cannot divide by zero\n";
else
return numerator/denominator;
}
The program will compile, and when I use two ints > 0 execution is normal. If I try to divide by 0 however, I get the following message:
terminate called after throwing an instance of 'char const*'
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Process returned 255 (0xFF) execution time : 4.485 s
Press any key to continue.
I've looked at other examples, but have yet to find similar code to derive an answer from.
Any advice?
There's a compelling example in the C++ Standard, [except.throw]/1:
Example:
throw "Help!";
can be caught by a handler of const char* type:
try {
// ...
} catch(const char* p) {
// handle character string exceptions here
}
When you throw via throw "Error: Cannot divide by zero\n";, the expression after throw is a string literal, therefore of type array of n const char (where n is the length of the string + 1). This array type is decayed to a pointer [except.throw]/3, therefore the type of the object thrown is char const*.
Which types are catched by a handler (catch) is described in [except.handle]/3, and none of the cases apply here, i.e. the const char* is not catched by a handler of type char*.