C++ If-else Branch wont produce an output - c++

hope all is well. I was working on some code (C++) that would determine the season depending on the users input. The user is meant to type in a valid month and date in a year and from that the code is supposed to determine the season. Per instructions provided by my professor:
The dates for each season are:
Spring: March 20 - June 20
Summer: June 21 - September 21
Autumn: September 22 - December 20
Winter: December 21 - March 19
I was working on Spring for now, and this is the code I have. Just a little heads up, when inputting values March 20 - March 31, the code runs to my expectation and prints what is being looked for. However, when I type in any value such as June 1 - June 20 the program compiles, but it does not produce an output.
Here is the link to my code: https://repl.it/repls/FlippantAgileTheory
And here is the code:
using namespace std;
int main() {
string inputMonth;
int inputDay;
cin >> inputMonth;
cin >> inputDay;
if (inputMonth == "March" || inputMonth == "June") {
if (inputMonth == "March") {
if (inputDay > 19 && inputDay < 32) {
cout << "Spring\n";
}
else if (inputMonth == "June") {
// this is the aspect of the code that doesn't work
if ((inputDay > 0) && (inputDay < 21)) {
cout << "Spring\n";
}
}
}
}
}

The probable reason why good code needs to be well indented.
You can easily debug it if you indent it properly
Like-
if(inputMonth=="March"){
...
}
else if(inputMonth=="June"){
...
}
Also I think it would be better to use switch-cases here for the months differently other than using nested if-else statements that much, use the month names in an enum class for better code quality.

The problem becomes obvious if you add proper formatting.
All your print statements are within the block
if (inputMonth == "March") {
// ...
}
That means that no other month can cause any printing.
You probably meant
if (inputMonth == "March") {
// ...
}
else if (inputMonth == "June") {
// ...
}

It's important to make sure the code is properly formatted.
In your case, I assume what you meant to implement is:
if (inputMonth == "March" || inputMonth == "June"){
if (input == "March") {
if (inputDay > 19 && inputDay < 32){
cout << "Spring\n";
}
}
else if (input == "June") {
if ((inputDay > 0) && (inputDay < 21)){
cout << "Spring\n";
}
}
}
Just making changes to your brackets placement to make sure your if and else match properly will get the code working in no time.
I hope this helps.

Related

Checking a date is in an interval given by partial/periodic dates

I can define an interval with start and end in the format YYMMDD, but they can also be partial/periodic - meaning some elements (day, month or year) can be left blank.
For example, start = " 1115" and end = " 0115" the interval is 15th nov to 15th jan every year.
I want to check if a non-partial date is in the interval.
int compareParial(const char* first, const char* second)
{
for (int i = 0; i < 6; ++i)
{
if (first[i] != ' ' && second[i] != ' ' && first[i] != second[i])
return first[i] > second[i] ? 1 : -1;
}
return 0;
}
bool isDateInInterval(const char* start, const char* end, const char* searchDate)
{
int firstCompare = compareParial(start, searchDate);
int endCompare = compareParial(end, searchDate);
if (firstCompare <= 0 && endCompare >= 0)
return true;
// the date can still be in the interval if the start of the interval is in one year, but end in the next year
bool switched = 0 < compareParial(start, end);
if (switched && (firstCompare <= 0) != (endCompare >= 0))
return true;
return false;
}
int main()
{
cout << boolalpha << isDateInInterval(" 1115", " 0115", "251110") << endl;
return 0;
}
Update: If the dates are reversed check again if searchDate is in.
A problem I notice is what if start and end are reversed but the year is provided. For example: isDateInInterval("200105", "190601", "251110") would be true
C++20 contains types which can represent partial dates: year, month, day, year_month, month_day, etc.2
For example:
auto start = November/15;
auto end = January/15;
By using actual calendrical types, as opposed to strings, the logic you have to deal with can be greatly simplified. A complete year_month_day might be compared against an interval defined by a pair of month_day like this:
bool
compare_partial(std::chrono::month_day start, std::chrono::month_day end,
std::chrono::year_month_day searchDate)
{
using namespace std::chrono;
// Guess that both start and end fall in the same year
auto trial_start = start/searchDate.year();
auto trial_end = end/searchDate.year();
if (trial_start <= trial_end)
{
return trial_start <= searchDate && searchDate <= trial_end;
}
// start/y > end/y
// Otherwise guess that searchDate comes after trail_start:
if (trial_start <= searchDate)
{
// trial_end must be in the next year
trial_end += years{1};
return trial_start <= searchDate && searchDate <= trial_end;
}
// Otherwise searchDate < start/y && start/y > end/y
// trial_start must be in the previous year
trial_start -= years{1};
return trial_start <= searchDate && searchDate <= trial_end;
}
Be forewarned that even this answer is somewhat wrong1. However by using actual calendrical types to do things like add/subtract a year, and do the comparisons, one makes the code cleaner, easier to read, and thus less likely to contain errors.
This answer also only addresses the month_day partial date. You might also have a year_month partial date, or a mixture of month_day and year_month.
std::chrono has no type year_day, and I'm not sure what that would mean anyway. If you have an idea of what it would mean, I have no doubt that C++20 chrono could help you model it.
In any event:
cout << boolalpha << compare_partial(November/15, January/15, 2025y/November/10) << endl;
will output:
false
Even if you don't use C++20 chrono (or it's free preview), modeling this using calendrical types (perhaps of your own making), as opposed to strings, is highly recommended for creating a robust, error-free solution.
1 Expressions such as trial_end += years{1}; aren't guaranteed to be valid dates. For example what if trial_end has the value 2020-02-29. Adding a year to that will give you 2021-02-29. To make this correct, you must decide how you want to handle such situations (e.g. map it to 2021-02-28?).
2 There also exists a free, open-source, header-only preview of this part of C++20 which works with C++11/14/17: https://github.com/HowardHinnant/date
If year is set, and the dates are switched, you must return false, since it is an empty interval.
bool switched = 0 < compareParial(start, end);
if (start[0]==' ' && switched && (firstCompare <= 0) != (endCompare >= 0))
return true;
return false;

Program works fine in Debug, but not in Release

I made a tic-tac-toe game which works good. Recently I decided to add a reset game feature.
Here is the part where I take input from user
void playerMove() //Gets the player move and updates the box variables
{
int boxnumber;
while(1) //Set's loop if the player enters a invalid input
{
cout << "\n Player " << player << "'s turn!(Press 0 to reset the game!): ";
cin >> boxnumber;
if(box[boxnumber-1] == 'X' || box[boxnumber-1] == 'O' || boxnumber > 9 || boxnumber < 0) // Checks if the input is valid or not
{
system("CLS");//If invalid, show error and loop back to start to get new input
displayBoard();
cout << "\n Invalid Input! Try again!\n";
}else if(boxnumber == 0)
{
refreshGame();
displayBoard();
}else
{
box[boxnumber-1] = player;//If inputs are fine, set the box variable's and break out of loop!
break;
}
}
}
Now, in debug mode, when I press 0, everything runs fine and the game is reset, but in release build, when I press 0, it gives me the "Invalid Input! Try again!"
Things I have tried the didnt work:
-Rebuild the entire release and debug version.
-Making a new project and copy-pasting my code. Same thing, debug works, release doesnt.
For anyone wondering, I am using code::blocks IDE. The compiler is GNU GCC.
Thanks for the help! :)
You have undefined behavior.
In the "first" if you have box[boxnumber-1], so when you enter 0 (as you have stated in your question), you're trying to access element with index -1. That's UB, as you're reading "invalid" memory.
You should check for 0 first (and for negative numbers also).
In the if statement, put the range checks in front of the value checks. That is, change
if(box[boxnumber-1] == 'X' || box[boxnumber-1] == 'O' || boxnumber > 9 || boxnumber < 0)
to
if(boxnumber < 0 || box number > 9 || box[boxnumber-1] == 'X' || box[boxnumber-1] == 'O')
That takes advantage of short-circuiting: if the input value is less than 0 or greater than 9 the value checks won't be executed. That will avoid checking things like box[10], which isn't valid.
That still leaves a problem: if the user inputs 0, this code will happily check box[-1], which is also out of range. To get rid of this, move the branch of the if statement that tests box number == 0 in front of this part:
if (box number == 0)
// whatever
else if (box[boxnumber-1] == 'X' || box[boxnumber-1] == 'O' || boxnumber > 9 || boxnumber < 0)
// whatever else

If-else loop to find solution

My code is:
#include<stdio.h>
void main(void)
{
float timeLeavingTP;
int transitNumber;
float transitTime;
printf("Please enter the time leaving TP.\n");
scanf_s("%f",&timeLeavingTP);
printf("Please enter bus number.\n");
scanf_s("%d",&transitNumber);
if(timeLeavingTP==1.00)
{
if(transitNumber==27)
{
transitTime=1.56;
}
else if(transitNumber==8);
{
transitTime=1.39;
}
}
if(timeLeavingTP==6.30)
{
if(transitNumber==27)
{
transitTime=7.32;
}
else if(transitNumber==8)
{
transitTime=7.29;
}
printf("The time reached home is %f\n",transitTime);
}
}
After debugging i got
Please enter the time leaving TP
1.00
Please enter bus number
27
Please enter to continue...
My question is How do i adjust the program to make it look like the one below instead. What kind of error did i commit?
Please enter the time leaving TP
1.00
Please enter bus number
27
The time reached home is 1.56
Thanks for the help in advance!
Hi guys after including == i still got the same for my debugging? Is there something else that i did wrong?
Part 1: = vs ==
Note that:
if(timeLeavingTP=1.00)
Does not do what you expect. It assigns timeLeavingTP with 1.00.
You probably want:
if(timeLeavingTP==1.00)
Additionally, note that this error occurs 6 times in your program.
Part 2: comparing floating point numbers
Your code might work in this case, but I'm not 100% sure if it will or not. It's often difficult to directly compare 2 floating point numbers, because of the inaccuracy of storing them (for example, 0.1 is usually not representable in floating point).
Most people solve this problem in one of a few ways:
Test a range around the number.
Convert to some fixes width format. Perhaps you could store the number as an integer, knowing that it's representation is actually 0.01 * the stored number.
In this case, you could actually just store the information as strings, and compare those.
Part 3: conditionals
To write a proper conditional, it should look like:
if (condition) {
...
} else if (condition) {
...
} else if (condition) {
...
} else {
...
}
You can certainly nest conditionals as well:
if (condition) {
if (condition) {
...
} else {
...
}
} else if (condition) {
...
}
Your code, for example, messes this up when you do:
}
else(transitNumber=8);
{
transitTime=1.39;
}
Note that the else statement does not accept a conditional after it.
Part 4: excessive semicolons
Additionally, note that after the else and if statements there are no semicolons. The semicolons only appear within the braces. So this statement:
if(timeLeavingTP=6.30);
While semantically valid, does not do what you expect. You actually want to remove that semicolon.
if(timeLeavingTP == 1.00)
{
if(transitNumber == 27)
{
transitTime=1.56;
}
else if(transitNumber == 8)
{
transitTime=1.39;
}
}
else if(timeLeavingTP == 6.30)
{
if(transitNumber == 27)
{
transitTime == 7.32;
}
if(transitNumber ==8)
{
transitTime=7.29;
}
}
printf("The time reached home is %f\n",transitTime);
}
if(transitNumber=27)
{
transitTime=1.56;
}
else(transitNumber=8);
{
transitTime=1.39; //this line is executed all the time
}
This code is completly invalid!
First, you do not compare anything... transitNumber = 27 is an assignment.
Second else(transitNumber=8); again this is an assignment and it should be else if(...). Also ; at the and means that transitTime = 1.39(inside bracket) will always happen, even if transitNumber != 8
Change
if(timeLeavingTP=1.00)
to
if(timeLeavingTP==1.00)
so that you can compare timeLeavingTP correctly.

Nested If dilemma

I am having troubles understanding this issue. The code is really basic but it behaves rather unexpectedly. The code is the simplified version of a routine to extract and save to a separate file the data for the day 15 of each month out of a daily database. Where is the problem ? The first cout prints the number of any day the outer if is entered. Then there are some conditional lines to select the right day ( not really important in this example ) and then there is the block, the inner if, that should print the data for the day 15 to the new file. Now, as you can see, while the outer loop ( attention ! ) is entered only on the 10th ( and this is already wrong - it should have written all the numbers from 11 to 15 ) but then it also prints that the file is written on the 15 ! Where is the problem ? The OUTER IF was entered only on the 10th, how can be the INNER IF be execute on the 15th ????
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
string newdata="mamma";
string risultato="-";
string PriorLine="-";
int PriorDay=0;
int lastmonth=0;
// Loops through all the months
for (int mese=1; mese <=12; mese++)
{
//Loops through all the days in the month
for(int day=1; day<=30; day++)
{
// at the month's beginning these 2 strings are set ="-"
if (mese != lastmonth)
{
risultato="-";
PriorLine="-";
}
// if we are between the 10th and the 20th and the result is still to be found
if (day>=10 && day<=20 && risultato=="-")
{
cout << day << endl; // LISTS ALL THE DAYS THIS LOOP IS ENTERED
if (day=15) // if it is exactly day 15 print that day's result
risultato=newdata;
// if that month in the data there is no day 15 and
// this is the second pass, choose the closest !
if (day>15 && PriorLine !="-")
{
if (abs(day-15)<=abs(15-PriorDay))
risultato=newdata;
else
risultato=PriorLine;
}
PriorLine=newdata;
PriorDay=day;
if (risultato != "-")
{
// writes the result ( risultato ) in a file
cout << "file written on the " << day << endl;
}
}
lastmonth=mese;
}
}
system("pause");
return 0;
}
if (day=15) assigns 15 to day and returns true. You need if (day==15)
When I simply compiled your code with g++ -Wall I got a warning:
error: suggest parentheses around assignment used as truth value
On this line:
if (day=15) // if it is exactly day 15 print that day's result
I'm willing to be the compiler has told you what your problem is. I suggest you enable all warnings in your build system.

expected primary-expression before 'else'

I have an emergency here. This homework is due tomorrow for my CP 1 class. We have to make a simple dice game. If you get doubles of the same number, then good things happen. Here is the function:
void Doubles(); //prototype for the function Doubles()
//pre: n/a
//post: Plays a simple dice game with the user
void Doubles()
{
//variables declared to store dice values
int DieOne, DieTwo, PlayerSame, ComputerSame;
cout<<"\nLET'S PLAY DOUBLES!!!\n"<<endl;
srand ( time(NULL) ); //initialize random seed
DieOne = rand()%6 + 1;
DieTwo = rand()%6 + 1;
cout<<"\nYour first die is a "<<DieOne;
cout<<"\nYour second die is a "<<DieTwo;
if(DieOne == DieTwo)
{
PlayerSame = 1;
}
else
{
PlayerSame = 0;
}
DieOne = rand()%6 + 1;
DieTwo = rand()%6 + 1;
cout<<"\n\nThe computer's first die is a "<<DieOne;
cout<<"\nThe computer's second die is a "<<DieTwo;
if(DieOne == DieTwo)
{
ComputerSame = 1;
}
else
{
ComputerSame = 0;
}
if(PlayerSame == 1 && ComputerSame == 0)
{
cout<<"\n\nYou win! Your dice are the same and the "
<<"computer's dice aren't!";
}
else if(PlayerSame == 1 && ComputerSame == 1)
{
cout<<"\n\nYou tied! Your dice are the same and the "
<<"computer's dice are the same!";
}
else if(PlayerSame == 0 && ComputerSame == 1)
{
cout<<"\n\nYou lost! Your dice are not the same, and the "
<<"computer's dice are!";
else
{
cout<<"\n\nNeither you nor the computer had dice that matched, "
<<"so you both lose!";
}
}
So why, wen I run this, am I getting the compiler error stated in the title? the primary expression is right there! The "else" it's referring to is the last one there. Any help is greatly appreciated.
You are missing the brace, as has been pointed out, but the flaw comes from not being able to look at the code indentation correctly and not being able to clearly see the error. The indentation on the else if's is indented one more than the if, and if this were not the case, you would quickly see the missing brace, but, as formatted, it is more easily missed, although I did not even read the whole post before looking at the code and spotting the missing brace myself (I have a lot of legacy code which I maintain that has bad indentation that I have been fixing for years, and this is a common type of formatting error that leads to this specific problem.. Proper formatting would lead to the spotting of this type of error much more quickly, especially in programmers that have not been programming for a long time and are not seasoned to fix the formatting in their head as they read through before looking at code specifics.
Jay
you forgot the closing brace for the block after the second else if
Looks like you are missing a brace } after <<"computer's dice are!"; line.
Doesn't your compiler tell you the line number where it sees the error?
PLease add the closing brace before the else.
else if(PlayerSame == 0 && ComputerSame == 1)
{
cout<<"\n\nYou lost! Your dice are not the same, and the "
<<"computer's dice are!";
}
else
{
cout<<"\n\nNeither you nor the computer had dice that matched, "
<<"so you both lose!";
}