Hi I'm learning the basic of C++ and I'm in the process of doing an assignment. I'm asking if there is a simpler way to write this part.
if ( 100 >= projectgrade && 0<= projectgrade ) {}
else
{
cout<<endl<<"invalid data, please retry again.";
cin.ignore();
cin.get();
return EXIT_SUCCESS;
}
if ( 100 >= midtermgrade && 0<= midtermgrade ) {}
else
{
cout<<endl<<"invalid data, please retry again.";
cin.ignore();
cin.get();
return EXIT_SUCCESS;
}
if ( 100 >= finalexamgrade && 0<= finalexamgrade ) {}
else
{
cout<<endl<<"invalid data, please retry again.";
cin.ignore();
cin.get();
return EXIT_SUCCESS;
}
Is it possible to write all those restriction in one bracket of if? I try numerous time but I can't figure it out. Ty for helping out!
Well, if you examine your logic it's if any of the grades is less then 0 or greater then 100, so something like this -
if ( projectgrade < 0 || projectgrade > 100 ||
midtermgrade < 0 || midtermgrade > 100 ||
finalexamgrade < 0 || finalexamgrade > 100
) {
cout<<endl<<"invalid data, please retry again.";
cin.ignore();
cin.get();
return EXIT_SUCCESS;
}
Edit
and we could always add a #define like
#define range(x) x < 0 || x > 100
then that if could be shortened to
if (range(projectgrade) || range(midtermgrade) || range(finalexamgrade))
if ( (projectgrade <0) || (projectgrade > 100) || (midtermgrade <0) || (midtermgrade > 100) || (finalexamgrade < 0) || (finalexamgrade > 100))
{
cout<<endl<<"invalid data, please retry again.";
cin.ignore();
cin.get();
return EXIT_SUCCESS;
}
In C++11 you can write:
auto failure = [](){
cout << "invalid data, please try again" << endl;
cin.ignore();
cin.get();
return 0;
};
and then use it when failures happen:
if ( !(100 >= projectgrade && 0<= projectgrade) )
return failure();
// do more stuff
if ( !(100 >= midtermgrade && 0<= midtermgrade) )
return failure();
Note, doing endl after your text instead of before it is preferable; return 0; always indicates success, and cin.ignore() just ignores a single character (in general, you may want to ignore the rest of the line).
First you may add a function for the test
bool is_valid_grade(int grade)
{
return 0 <= grade && grade <= 100;
}
or
bool is_valid_grade(unsigned int grade)
{
return grade <= 100; // unsigned cannot be negative
}
then use it like:
if (is_valid_grade(projectgrade)
&& is_valid_grade(midtermgrade)
&& is_valid_grade(finalexamgrade))
{
// Valid code
}
else
{
return failure(); // your previous code into a function
}
Related
I am making a C++ code where you will create an array using a do while loop.
Here is the full code:
const int size = 10;
double *pt1;
//executable
pt1=new double[size];
int i = 0;
do{
cout <<"mile" << "[" << i << "]" << setw(3);
if(*(pt1+i) >= 100 && *(pt1+i) <= 250)
{
cin >> *(pt1+i);
i++;
}
else if( *(pt1+i) > 100 && *(pt1+i) < 250)
{
cout << "100-250 only";
continue;
}
}while(i < 10);
There is an input validation where the numbers that will be accepted are only numbers from 100 to 250 but it keeps on looping. I can't find where the problem is. Any help would be greatly appreciated!
The first error is that you are testing the value of the input before you actually get the input. That makes no sense, you need to switch the order around. So this
if(*(pt1+i) >= 100 && *(pt1+i) <= 250)
{
cin >> *(pt1+i);
...
}
else if( *(pt1+i) > 100 && *(pt1+i) < 250)
{
...
}
should be this
cin >> *(pt1+i);
if(*(pt1+i) >= 100 && *(pt1+i) <= 250)
{
...
}
else if( *(pt1+i) > 100 && *(pt1+i) < 250)
{
...
}
Secondly I think you meant
else if( *(pt1+i) < 100 || *(pt1+i) > 250)
Or better you could have just said
else
Then there is no chance of getting the logic wrong. When you have only two choices, you just need to test for the first choice and use else for the second choice. There's no need to test for the opposite of the first choice, using a plain else will do that automatically.
Also continue at the end of a loop is not necessary, loops continue automatically.
Finally pt1[i] is much easier to read than *(pt1+i).
I'm writing a simple function that is supposed to read an input from a user as a string. Check if the strings solely consist of digits then converts it to and int and returns it. The problem is the loop never used regardless of the input. I'm struggling to find the root of the problem.
int correctInt()
{
string temp;
int input;
bool m;
do
{
m = false;
getline(cin, temp);
int length=temp.length();
for (int a = 0; a < length; a++)
{
if (temp[a] < '0' && temp[a]>'9')
{
cout << "ID should consist of numbers. Try again: ";
m = true;
break;
}
}
if (!m)
{
return input = atoi(temp.c_str());
}
} while (1);
}
Thank you in advance
You should use OR instead of AND:
temp[a] < '0' || temp[a]>'9'
Try to change && (and) condition to || (or) condition
if (temp[a] < '0' || temp[a]>'9')
I need to create a program that gets 6 random integer inputs(3 even, 3 odd; in any order) and then displays the smallest even and odd integer inputted. My code almost does exactly that except if you enter a number such as -6 for the first variable and go all the way to -1 for the last variable, the smallest even is counted as -4 and the smallest odd is -5. What exactly is going wrong that makes this happen?
short int a, b, c, d, e, f, smallEven=0, smallOdd=0;
cout<<"Enter a number: "; //test a-c: even or odd; is there a small even or small odd; if there is, is new input smaller than old?
cin>>a;
if (a%2==0){
if (smallEven==0)
smallEven=d;
else if (a<smallEven)
smallEven=a;
}
else if (a%2== 1 || a%2== -1){
if (smallOdd==0)
smallOdd=a;
else if (a<smallOdd)
smallOdd=a;}
cout<<"Enter a number: ";
cin>>b;
if (b%2==0){
if (smallEven==0)
smallEven=b;
else if (b<smallEven)
smallEven=b;
}
else if (b%2==1 || b%2== -1){
if (smallOdd==0)
smallOdd=b;
else if (b<smallOdd)
smallOdd=b;}
cout<<"Enter a number: ";
cin>>c;
if (c%2==0){
if (smallEven==0)
smallEven=c;
else if (c<smallEven)
smallEven=c;
}
else if (c%2== 1 || c%2== -1){
if (smallOdd==0)
smallOdd=c;
else if (c<smallOdd)
smallOdd=c;}
cout<<"Enter a number: "; //at this point only need to ask if input is even or odd, and if its the smallest
cin>>d;
if (d%2==0){
if (d<smallEven)
smallEven=d;
}
else if (d%2== 1 || d%2== -1){
if (d<smallOdd)
smallOdd=d;}
cout<<"Enter a number: ";
cin>>e;
if (e%2==0){
if (e<smallEven)
smallEven=e;}
else if (e%2== 1 || e%2== -1){
if (e<smallOdd)
smallOdd=e;}
cout<<"Enter a number: ";
cin>>f;
if (f%2==0){
if (f<smallEven)
smallEven=f;}
else if (f%2== 1 || f%2== -1){
if (f<smallOdd)
smallOdd=f;}
void smallest(int* even, int* odd, int n){
if(n%2 == 0 && n < *even) *even = n;
else if(abs(n%2) == 1 && n < *odd) *odd = n;
}
then you could do something like this
int n, even, odd;
while(cin >> n){
smallest(&even, &odd, n);
}
if you need to do it this way for an assignment the logic seems right but check the variables very carefully. I see some typos in the first block.
The problem with lots of repeated code is that you often make cut'n'paste errors while copying it. That's evident in your first section if that you cin >> **a** but then if (smallEven==0) smallEven=**d**.
The ideal way to do this would be to break it up into functions but, since you state you're not allowed to do that due to course restrictions, you can still greatly clean up your code by realising you don't need a lot of variables.
int num, smallEven, smallOdd, countEven = 0, countOdd = 0;
while ((countEven < 3) && (countOdd < 3)) {
cin >> num;
// Select even or odd.
if ((num % 2) == 0) {
// Check allowed.
if (countEven == 3) {
cout << "No more even numbers allowed\n";
continue;
}
// Store if first or lesser, add to count.
if (countEven == 0) {
smallEven = num;
} else {
if (num < smallEven) {
smallEven = num;
}
}
countEven++;
} else {
// Check allowed.
if (countOdd == 3) {
cout << "No more odd numbers allowed\n";
continue;
}
// Store if first or lesser, add to count.
if (countOdd == 0) {
smallOdd = num;
} else {
if (num < smallOdd) {
smallOdd = num;
}
}
countOdd++;
}
With functions, this becomes even easier:
void apply(const char *type, const int num, int &count, int &small) {
if (count == 3) {
cout << "No more " << type << " numbers allowed\n";
return;
}
// Store if first or lesser.
if (count == 0) {
small = num;
} else {
if (num < small) {
small = num;
}
}
count++;
}
:
int num, smallEven, smallOdd, countEven = 0, countOdd = 0;
while ((countEven < 3) && (countOdd < 3)) {
cin >> num;
// Select even or odd.
if ((num % 2) == 0)
apply("even", num, countEven, smallEven);
else
apply("odd", num, countOdd, smallOdd);
}
#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <stdlib.h>
using namespace std;
int main()
{
int x,y,z;
cout<<"welcome to guessing game\nplayer one pick your number: ";
cin>>x;
if (x < 0)(x > 100);
{
cout<<"out of number range";
}
Sleep(2000);
system("cls");
cout<<"ok player 2 pick the guess";
cin>>y;
if (x == y){
cout<<"congrats you got it right";
}
else{
if (x < y){
cout<<"Go lower";}
else {
if (x > y){
cout<<"higher";}}
}
system("pause>nul");
return 0;
}
i cant see the get the initial if statement to work no matter what number i type in it would auto display the out of number range. also am i allowed to place the conditions like that soo close like if (x < 0)(x > 100);. also how do i make it soo it returns to the start of the program?
There is an error:
if (x < 0)(x > 100);
{
cout<<"out of number range";
}
Should be:
if (x < 0 || x > 100)
{
cout<<"out of number range";
}
You also need to work on your indentation; those if/else statements towards the bottom look dodgy (I cannot really tell due to the indentation).
Aside from writing if (x < 0 || x > 100) (and dropping the semicolon), you should be wary of comparing equality on floating point. I would red flag your line if (x == y){ if reviewing your code.
See Floating point comparison
nobody else is actually answering your second question: how to loop it, here you go:
int x;
cout << "Welcome to the guessing game\n";
do {
cout << "Please enter a number from 0 to 100: ";
cin >> x;
} while (x < 0 || x > 100);
You have written
if (x < 0)(x > 100);
{
cout<<"out of number range";
}
First remove the semi colon.
Second did you mean
if ((x < 0) || (x > 100))
{
cout<<"out of number range";
}
try this:
/*
if (x < 0)(x > 100);
{
cout<<"out of number range";
}
*/
if (x < 0 || x > 100)
{
cout<<"out of number range";
}
There are a few notable syntax errors:
if (x < 0)(x > 100);
{
cout<<"out of number range";
}
First of all, you can't just put two conditions side by side like that in C++ that I know of. You'd have to separate them with || for OR, or && for AND (in most cases - there are some others).
Also, you had a ; at the end of your if statement. I believe that doing this in C++ will result in some problems too.
Your final code should look like:
if ((x < 0) || (x > 100))
{
cout << "out of number range" << endl;
}
The << endl; part is optional. This adds a new line to your output, for more readability next time you write something.
Also, to loop your entire game repeatedly, I would use a do-while loop. You can learn about them here.
I'm having trouble with this C++ code. The integer num is a number that I want to check if it is prime. However this program is always returning false. It's probably something simple but I can't find anything.
for(int i=2;i<num;i++){ //primes are allowed to be divided by 1 so we start at 2
if(num % i == 0){ //can be divided by a number other than itself or 1 so we trip out
return false;
} else if(i == num){ //if we've already done checks as high as possible and not tripped out yet then report success
return true;
}
}
i == num will never occur, since your loop condition is i<num. Try:
for(int i=2;i<num;i++){ //primes are allowed to be divided by 1 so we start at 2
if(num % i == 0){ //can be divided by a number other than itself or 1 so we trip out
return false;
} else if(i == num-1){ //if we've already done checks as high as possible and not tripped out yet then report success
return true;
}
}
As pointed out below, the else condition here is redundant, and you only need to check from 2 to sqrt(num) - since the remaining factors have already been checked.
There are more improvements that can be made depending on how complex you want to make the problem. Most methods in reality use probabilistic algorithms.
You don't have to check every number, as a lot of them can easily be ruled out. For example, after checking that num is not divisible by 2, you can skip all other even numbers. That saves you half the tests.
We also definitely know that any other factor must be less than num/2 (or really sqrt(num), but that is harder to compute). That knowledge can save us another half of the tests.
So now we have:
if (num % 2 == 0)
return false;
for(int i = 3; i < num / 2; i += 2){
if(num % i == 0){ //can be divided by a number other than itself or 1 so we trip out
return false;
}
}
// arriving here we have found no factors, so it must be a prime
return true;
A small optimization for Will Ness's code, just calculate the sqrt of the number outside the for. The condition check executes many times and has no sense to calculate sqrt each time.
if( num == 2 ) return true;
if( num < 2 || num % 2 == 0 ) return false;
int sqrt = sqrt(num);
for( int i=3; i<=sqrt; i+=2 ){
if(num % i == 0){
return false;
}
}
return true;
So far I think that this is the most efficient way!
bool CheckPrime(int num) {
bool yayornay = true;
for(int i = 2; i < num; i++) {
if(num % i == 0) {
yayornay = false;
break;
}
}
return yayornay;
}
bool isprime(int n)
{
if(n<2) return false;
if(n==2)return true;
for(int i=2;i<=sqrt(n);i++)
if(n%i==0) return false;
return true;
}
Here's the proper way to write what you meant:
int i=2; // move declaration out
for(/*int i=2*/;i<num;i++){
if(num % i == 0){
return false;
} // else // and the final test too
}
if(i == num){
return true;
}
But that's not efficient. You only have to check for i's not exceeding of sqrt(num). Plus, if you check num%2, there's no more need to check any other even numbers, so you can use an increment of 2. Or you can even count by 6:
if( num == 2 || num == 3 ) return true;
if( num < 2 || num % 2 == 0 || num % 3 == 0 ) return false;
for( int i=5, j=7, lim=sqrt(num); i<=lim; i+=6, j+=6 ){
if( num % i == 0 || num % j == 0 ){
return false;
}
}
return true;
(notice: this is more efficient than another answer here, which says it's an "optimization" of an initial version of this answer).