Assert function causes program to crash - c++

I have used assert function to ensure that the first number input is between 1 and 7 (inclusive). However, when I execute the program and enter an invalid number, it causes the program to crash. So, how is the assert function being of any use here if that's the case?
Please correct my implementation where required.
Code:
#include <iostream>
#include <assert.h>
using namespace std;
int main() {
int num;
int n;
int max;
cout << "Please enter a number between 1 & 7 \n";
cin >> num;
assert(num >= 1 && num <= 7);
for (int i = 0; i < num; i++) {
cout << "Please enter number " << (i + 1) << ": ";
cin >> n;
if (i == 0) {
max = n;
}
max = (n > max) ? n : max;
}
cout << "The maxmum value is: " << max << endl;
system("pause");
return 0;
}

Assert is not what you want here. What you need is validation. Assertions are for debugging, for identifying completely invalid program states. The user entering invalid input is not invalid program state, it's just invalid user input.
To perform validation, you need an if-test. You will also need some code ready to handle the case of invalid user input. There's absolutely no way to prevent the user from providing invalid input (short of insanely aggressive dynamic validation where you capture keyboard events as they occur and prevent those keystrokes from translating into character input to your program, but now we're just getting ridiculous), so you need to react to it when it happens, say, by printing an error message and then asking for more input.
One way of doing this is as follows:
do {
cin >> num;
if (!(num >= 1 && num <= 7)) {
cerr << "invalid number; must be between 1 and 7!" << endl;
num = -1;
}
} while (num == -1);
Just to expand on that point about assertions, they are supposed to make the program crash. An assertion failure means your code is broken and must be fixed before it can be used in real life. Assertion failures should never be triggered in production code; they simply aid in testing and catching bugs.

What does the "crash" does? According to me, assert will abort the program execution, maybe as another value other than 0.

Related

Code gives desired output but keeps on running

This code I wrote is supposed to subtract one from the number inputed, or divide by 2 based on whether it is a multiple of 3 or not. However, every time I try to run the code, It outputs the numbers I want but then doesn't stop running. I am new to coding and not sure how to fix this.
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main() {
int n;
cout << "Enter a positive number: " << endl;
cin >> n;
if (n < 0) {
cout << "Invalid input." << endl;
}
while (n >= 1) {
if (n % 3 == 0) {
n = n-1;
cout << n << endl;
}
else if (n % 3 != 0) {
n = n / 2;
cout << n << endl;
}
}
return 0;
}
This is a screenshot of the output I get. Instead of giving me the opportunity to run the code again it just stays like this:
I may be misunderstanding what you're asking, however, traversing through the code you can identify that nothing is being done to make the code run again. You would need add what you have inside another while loop. This new while loop would be something like while (input != 0) then run everything you have. In your input statement you could say "Please enter a positive number or enter 0 to exit". This is just an example of an approach, but the premise is that you need something to keep this loop running.

C++ code - Error message when floating point is entered [duplicate]

I've written a program that returns the median value of a user-defined array. While I've put a few checks in my code (array size can not be negative) I keep running into one issue I simply can not fix (for clarity sake, assume strings and alphabetical characters will not be used).
All of my input values are int however the user could just as easily enter in a float. When they do this (either for size of array or entering in the element) it breaks my code. I've tried multiple things to try and catch this, but it seems like the way my program is getting the value doesn't allow for the catch in time.
#include <iostream>
using namespace std;
void sort(int * a,int n)
{
for(int i=0;i<n;++i)
for(int j=i+1;j<n;++j)
{
if(a[i]>a[j])
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}\
}
return;
}
int main()
{
int n;
int check;
int x;
cout<<"Enter length of array:";
cin>>n;
if (n < 0){
while (n < 0){
cout << "Please enter a length greater than 0" << endl;
cin >> n;
}
} else if (n % 1 != 0){
while (n % 1 != 0){
cout << "Whole numbers only! Try again" << endl;
cin >> n;
}
}
if (n == 0){
cout <<"You try to enter numbers, but there's no place to put them." << endl;
cout << ":(";
return 0;
}
int a[n];
cout<<"Enter values one by one:\n";
for(int i=0;i<n;++i){
cin >> x;
a[i] = int(x);
}
sort(a,n);
if (n % 2 == 1){
cout<<"Median is:"<<a[n/2]<<endl;
}
else{
float z = (float(a[n/2]) + float(a[(n/2)-1])) / 2;
cout << "Median is:" << z << endl;
}
return 0;
}
First thing I tried was catching the float like so
`if (n % 1 !=0){
while(n % 1 !=0){
cout << "Enter a whole number"
cin >> n
}
}`
This still broke my program. The odd thing was that I entered a float and then printed the value of n and it only showed the int value.
I tried using typeid.n() with #include <typeinfo>and comparing that to an int type to check it was the correct value, but that slipped through as well.
I tried doing an int cast, something like int(n) immediately after number was stored in n but before it went into a[n] and yet again, it still broke my code.
How can I check against float user-input and loop them until they give me an int?
You're reading into an int:
int x;
...
cin >> x;
So it will read what it can, then stop at e.g. a . and leave the rest on the stream (like if the user enters "123.4" you'll get 123 and then ".4" won't be consumed from the input stream).
Instead, you could read into a float:
float x;
...
cin >> x;
And do the appropriate math.
Alternatively you could read into a string and parse it into a float. That way you won't get stuck at letters and such either.
And the final option is to read into an int but handle any errors and skip the bad input, which is detailed at How to handle wrong data type input so I won't reproduce it here.
Which option you choose really just depends on what you want the behavior of your program to be and how strictly you want to validate input (e.g. round vs. fail if "2.5" is entered but an integer is expected, how do you want to handle "xyz" as input, etc.).

Infinite loop when using exceptions in c++11

I would like to create a c++11 program that takes in 10 positive integers and gives the user the total. In the event of a negative number or a char input, the exception should be thrown and the user must re enter their value.
The program below works with negative numbers. However, when I enter a character like "a", the program goes into an infinite loop and I cannot figure out why.
Any and all help will be appreciated
#include <iostream>
int main(){
int array[10] = {0};
int total = 0;
for(int i =0; i < 10; i++){
std::cout<<"Number "<< i+1 << ": " <<std::endl;
std::cin >> array[i];
try{
if(array[i] < 0 || std::cin.fail())
throw(array[i]);
}
catch(int a){
std::cout<< a <<" is not a positive number! "<<std::endl;
i-=1; // to go back to the previous position in array
}
}
for(int k = 0; k < 10; k++)
total+=array[k];
std::cout<<"Total: " <<total<<std::endl;
}
If you get invalid input there are two things to thing you need to do:
Clear the stream status. This is done using the clear function.
Remove the invalid input from the buffer. This is usually done using the ignore function.
As for your program, you don't need exceptions here, just using unsigned integers and checking the status is enough:
unsigned int array[10] = { 0 };
...
if (!(std::cin >> array[i])
{
std::cout << "Please input only non-negative integers.\n";
// First clear the stream status
std::cin.clear();
// Then skip the bad input
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Make sure the index isn't increased
--i;
}
To use exceptions similar to what you do now, the solution is almost exactly the same as above:
unsigned int array[10] = { 0 };
...
if (!(std::cin >> array[i])
{
throw i;
}
catch (int current_index)
{
std::cout << "The input for number " << current_index + 1 << " was incorrect.\n";
std::cout << "Please input only non-negative integers.\n";
// First clear the stream status
std::cin.clear();
// Then skip the bad input
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Make sure the index isn't increased
--i;
}
Do not forget to include limits header file while using following line in your code :
std::cin.ignore(std::numeric_limits::max(), '\n');
because numeric_limits template is defined in this header file !

C++ Infinite Loop causing a stack overflow error?

Okay, so I've been working on my calculator. I am currently trying to get it to tell the difference between a valid integer and a character. As an easy workaround I did:
int calc()
{
cout << "Number 1:"; cin >> fnum;
cout << "Number 2:"; cin >> snum;
if (snum <= -1000 || fnum <= -1000)
{
cout << ("Error: Invalid Number!") << endl;
calc();
}
else
{
ff();
}
return 0;
}
And whenever I enter in a character it goes into an infinite loop saying:
SymbolHere:Number 1:Number 2:
ff(); is calling in the calculation function.
I was wondering how to fix this and prevent a stack overflow/ infinite loop? Pastebin Link: http://pastebin.com/GxN2uJAQ
EDIT: ok, there are a number of things with this code.
wait = 0;
while (wait <= 5)
{
wait++;
}
will do absolutely nothing, your program will increment so fast this is undetectable to the human mind. I would recommend removing this entirely.
if (snum >= 0 || fnum >= 0)
{
cout << ("Error: Invalid Number!") << endl;
wait = 0;
while (wait <= 5)
{
wait++;
}
system("CLS");
calc();
}
why are you sending an error message if these numbers are valid? Unless you are only adding negative numbers, this should have a different range.
your function calls also never resolve back into main, instead they call each other (ff and calc) infinity, the program honestly has too many flaws and bad programming practices. Drop whichever tutorial/book you have and try finding a more up to date list(sorry for being harsh, but it has to be said).
C++ Primer Plus
CPlusPlus.com
TheNewBoston(Recommended)
You probably have an input fail by entering say a char for an int, you need to make sure to catch anything thrown by cin and clear the state:
std::string err = "error!";
try {
std::cin >> x;
if(!cin)
throw err;
//....
}
catch(std::string& ee)
{
std::cout << ee << std::endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
}
make sure to include <limits> in your file.

Is there a way to not include a negative number in an average, when entering a negative number is how you terminate the program?

Sorry about last time for those who saw my previous thread. It was riddled with careless errors and typos. This is my assignment:
"Write a program that will enable the user to enter a series of non-negative numbers via an input statement. At the end of the input process, the program will display: the number of odd numbers and their average; the number of even numbers and their average; the total number of numbers entered. Enable the input process to stop by entering a negative value. Make sure that the user is advised of this ending condition."
And here is my code:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int number, total1=0, total2=0, count1=0, count2=0;
do
{
cout << "Please enter a number. The program will add up the odd and even ones separately, and average them: ";
cin >> number;
if(number % 2 == 0)
{
count1++;
total1+=number;
}
else if (number >= 0)
{
count2++;
total2+=number;
}
}
while (number>=0);
int avg1 = total1/count1;
int avg2 = total2/count2;
cout << "The average of your odd numbers are: " << avg1 << endl;
cout << "The average of your even numbers are " << avg2 << endl;
}
It seems to be working fine, but when I enter a negative number to terminate the program, it includes it with the rest of the averaged numbers. Any advice to get around this? I know it's possible, but the idea escapes me.
Your main loop should be like this:
#include <iostream>
for (int n; std::cout << "Enter a number: " && std::cin >> n && n >= 0; )
{
// process n
}
Or, if you want to emit a diagnostic:
for (int n; ; )
{
std::cout << "Enter a number: ";
if (!(std::cin >> n)) { std::cout << "Goodbye!\n"; break; }
if (n < 0) { std::cout << "Non-positve number!\n"; break; }
// process n
}
After here:
cout << "Please enter a number. The program will add up the odd and even ones seperately, and average them: ";
cin >> number;
Immediately check if the number is negative
if(number < 0) break;
Now you wouldn't need to use your do-while loop in checking if the number is negative. Thus, you can use an infinite loop:
while(true) {
cout << "Please enter a number. The program will add up the odd and even ones seperately, and average them: ";
cin >> number;
if(number < 0) break;
// The rest of the code...
}
ADDITIONAL:
There is something wrong in your code. You aren't showing the user how much the number of even and odd numbers are, and the total number of numbers entered.
ANOTHER ADDITIONAL: You should use more meaningful variable names:
int totalNumEntered = 0, sumEven = 0, sumOdd = 0, numEven = 0, numOdd = 0;
Of course I am not limiting you to these names. You can also use other similar names.
FOR THE INTEGER DIVISION PROBLEM:
You must cast your expression values to the proper type (in this case, it is float). You should also change the averages variables' types to float:
float avg1 = float(total1) / float(count1);
float avg2 = float(total2) / float(count2);
Immediately after cin >> number, check for < 0, and break if so. Try to step through the program line by line to get a feel for the flow of execution. Have fun learning, and good luck!