issue when creating an "if-else" statement - if-statement

Hi i'm pretty new to java I've been having an issue when I attempt an "if-else" statement. I get syntax errors, which I'm not sure why. Thanks for your input.
import javax.swing.JOptionPane;
public class MagicDate {
public static void main(String [] args){
int month;
int day;
int year;
String input;
String message = ("This program will find a secret date");
JOptionPane.showMessageDialog(null, message);
input = JOptionPane.showInputDialog( " Enter a month of the in numeric "
+ "form");
month= Integer.parseInt(input);
input = JOptionPane.showInputDialog( " Enter a day of the in numeric"
+ " form");
day= Integer.parseInt(input);
input = JOptionPane.showInputDialog( " Enter a two digit year");
year = Integer.parseInt(input);
if(month * day == year);
{
JOptionPane.showMessageDialog(null, "The Date is Magic!");
}
else
{
(month * day != year);
JOptionPane.showMessageDialog(null, "The Date is not Magic");
}
System.exit(0);
}
}

You should remove the semicolon at the end of the line containing the if statement. Basically, the effect of the semicolon is adding an empty statement. So your code reads like this to the compiler:
If (...)
Do nothing;
// can't have an brace here since the if statement has already terminated.
{
...
}

Remove the semicolon:
if(month * day == year)

Remove ; after if condition
if(month * day == year); // remove ;
and missing if
else
{
(month * day != year); // add if before line and remove ;
JOptionPane.showMessageDialog(null, "The Date is not Magic");
}

Related

Defining an object using an explicit value constructor

I'm trying to do an exercise using classes to store dates (MM DD YYYY). I have two class constructors, one default that sets the Date values to a default, and one that uses explicit values sent from main() in my driver file.
However, after my declaration statement in main() to the explicit value constructor (to make date2) in my driver file, I'm getting errors that appear to indicate that date2 was never made.
Below are the relevant portions for this constructor. How do I get date2 to become defined and declared to use for other things in main()?
Header
class Date
{
private:
int month, day, year;
public:
Date(); // default date constructor will assign all data members to equivalent of 01/01/2022
Date(int initMonth, int initDay, int initYear); //parametered Date constructor will collectively set all three data members
}
Implementation
Date :: Date(): month(1), day(1), year(2022) {}
Date :: Date(int initMonth, int initDay, int initYear)
{
if (initMonth < 1 || initMonth > 12) { cerr << "Invalid month\n\n"; month = -2; }
if (initDay < 1 || initDay > 30) { cerr << "Invalid day\n\n"; day = -2; }
if (initYear < 1) { cerr << "Invalid year\n\n"; year = -2; }
month = initMonth;
day = initDay;
year = initYear;
}
Driver
Date date1;
do
{
cout << "Please enter a date in this sequence: MM DD YYYY ";
cin >> month >> day >> year;
Date date2(month, day, year);
} while (date2.month == -2 || date2.day == -2 || date2.year == -2);
date1.print();
date2.print();

Reading a date from a file

I am going to pipe in an input such as 2021/10/7 (Year/Month/Day). I wont be asking the user for input and I need the code to be able to read the input properly. I don't understand how to get input (a date) from Linux and how my program will transverse that input into its proper places inside of my code.
We've gone over <fstream> briefly and ifstream inData; ofstream outData; .open and .close but for my last assignment in the sample solution that was posted freopen was used which I am completely unfamiliar with. I have asked for help from my professor specifically but encourages using outside means like the compute science discord and tutoring which are not that much help.
What I'm looking for is a way to learn how to be able to input the data so that it can be read from the data stream and how I should structure something like this for getting input from Linux instead of the user.
Write a program that reads a date from the standard input stream.
If the date is valid, the program should write the weekday number followed by the English weekday name (e.g., "Monday", "Tuesday", "Wednesday", ..., "Sunday"). Function main returns 0.
If the date read from the standard input stream is invalid, the program should write "Error: invalid date". Function main returns 1.
Sample Interactions
$ echo "2021/03/01" | ./pa04
0 Monday
$ echo $?
0
$ echo " 2022/3/1" | ./pa04
1 Tuesday
$ echo $?
0
$ echo "3/1/2022" | ./pa04
Error: invalid date
$ echo $?
1
$ echo "abracadabra" | ./pa04
Error: invalid date
$ echo $?
1
#include iostream
#include string
#include iomanip
#include cmath
using namespace std;
int main() {
int day, month, year, w;
// When I get here I feel there needs to be a cin.ignore() for the '/' in 2021/10/07.
// But I'm also concerned that if someone puts in 7 instead of 07 like in the sample interactions that it will jack up the results.
cin >> year >> month >> day;
w = (day + (13 * (month + 1) / 5) + (year) + (year / 4) - (year / 100) + (year / 400)) % 7;
switch (w) {
case 1:
cout << "Sunday \n";
break;
case 2:
cout << "Monday \n";
break;
case 3:
cout << "Tuesday \n";
break;
case 4:
cout << "Wednesday \n";
break;
case 5:
cout << "Thursday \n";
break;
case 6:
cout << "Friday \n";
break;
case 7:
cout << "Saturday \n";
break;
}
return 0;
}
You are not handling the / characters at all.
You can use additional >> calls and variables for that:
int day, month, year;
char slash1, slash2;
if ((cin >> year >> slash1 >> month >> slash2 >> day) &&
(slash1 == '/') &&
(slash2 == '/'))
{
// use values as needed...
}
else
{
// invalid format...
}
Or, you can use istream::ignore() to skip the / characters:
int day, month, year;
if (cin >> year &&
cin.ignore(numeric_limits<streamsize>::max(), '/') &&
cin >> month &&
cin.ignore(numeric_limits<streamsize>::max(), '/') &&
cin >> day)
{
// use values as needed...
}
else
{
// invalid format...
}
Or, in C++11 and later, you can use std::get_time() to let the standard library read in and parse the date components for you:
#include <iomanip>
tm date;
if (cin >> get_time(&date, "%Y/%m/%d"))
{
int day = date.tm_mday;
int month = date.tm_mon + 1;
int year = date.tm_year + 1900;
int w = date.tm_wday + 1;
// use values as needed...
}
else
{
// invalid format...
}
Using std::get_time() has the added benefit that std::tm has a tm_wday member for the day of the week, as you can see above, so you don't have to calculate it manually.
You can use C++20's std::chrono for this as well. It lets you:
Parse an input string, in accord to a format specification, into a time object (e.g. days in a system clock).
Get the week day for that time object.
I've found however that the std::chrono's parse method:
Is not very flexible. AFAIK, it doesn't let you use regular expressions (for example, for matching whitespaces at the beginning of the input string, as in one of your input samples,
2022/4/2; this, in particular, would be easily fixed trimming the string before parsing it).
Can lead to some parsing surprises. For example, for another one of your input samples, 5/3/2023, it will interpret the date as the 20th of March of the year 5. That is, it will match the day to the first 2 digits, 20, of what should be the day in your input string, 2023.
So I would go for a mixed solution here:
a manual parsing of the input string into a time object.
then using std::chrono for geting the week day corresponding to that time object.
The code below implements both solutions in two different functions, using_just_chrono and using_regex_and_chrono, just to show the issues I mentioned above if we just use std::chrono. I have used regular expressions for the manual parsing but you could just capture the year, month, and day of each date with a string stream after doing some trimming.
#include <chrono> // parse, sys_days, weekday
#include <iostream> // cout
#include <regex> // regex_match, smatch
#include <sstream> // istringstream
namespace ch = std::chrono;
void using_just_chrono(const std::string& date)
{
ch::year_month_day ymd{};
std::istringstream iss{ date };
if (iss >> ch::parse(std::string{ "%Y/%m/%d" }, ymd) and ymd.ok())
{
std::cout << "\t\tusing just chrono: " << ch::weekday{ ch::sys_days{ ymd } } << "\n";
}
}
void using_regex_and_chrono(const std::string& date)
{
// Probably more portable using [[:space:]] and [[:digit:]] here
std::regex pattern{ R"(^\s*(\d{1,4})/(\d{1,2})/(\d{1,2})\s*$)" };
std::smatch matches{};
if (std::regex_match(date, matches, pattern))
{
ch::year_month_day ymd(
ch::year{ std::stoi(matches[1]) },
ch::month{ std::stoul(matches[2]) },
ch::day{ std::stoul(matches[3]) });
if (ymd.ok())
{
std::cout << "\t\tusing rgx and chr: " << ch::weekday{ ch::sys_days{ ymd } } << "\n";
}
}
}
int main()
{
std::cout << "Parsing dates:\n";
for (const std::string& date : {
"2021/03/01", // OK
" 2022/4/2", // OK: needs trimming white spaces at the front
"5/3/2023", // wrong: day is 2023
"abracadabra", // wrong format
"2020/12/32", // wrong: day is 32
"2019/13/20", // wrong: month is 13
"2021/2/29" }) // wrong: non existing date
{
std::cout << "\t\"" << date << "\":\n";
using_just_chrono(date);
using_regex_and_chrono(date);
}
std::cout << "\n";
}
// Outputs:
//
// Parsing dates:
// "2021/03/01":
// using just chrono: Mon
// using rgx and chr: Mon
// " 2022/4/2":
// using rgx and chr: Sat
// "5/3/2023":
// using just chrono: Sun
// "abracadabra":
// "2020/12/32":
// "2019/13/20":
// "2021/2/29":

Visual C++ doesn't recognize my function as a part of a class

I'm making a decent program that will take any date, and find the day before and after it. I have everything finished, except when I debugged it, I got around 13 errors! After reading the error statements, I figured that the function wasn't recognized as part of the class, but I have no idea why.
I feel like I understand what I'm doing, but there's something that's not right. If anyone has any suggestions, please let me know. Thank you!
I have three files:
Main File (Source.cpp):
#include <iostream>
#include <iomanip>
#include <string>
#include "DateType.h"
using namespace std;
int main() {
//Inputs
int month, day, year;
bool flag;
DateType today, tomorrow, yesterday;
do { //Registers input and checks if it can go through program
cout << "Enter the current month (1-12): ";
cin >> month;
cout << "Enter the current year: ";
cin >> year;
cout << "Enter in today's date: ";
cin >> day;
today.SetDate(month, day, year);
flag = today.valid_date();
} while (!flag);
//Equalizing all three objects
tomorrow = today;
yesterday = today;
//Moving ford and back one day
tomorrow.NextDay();
yesterday.PreviousDay();
//Output
cout << "Given Date: " << today.print_Day() << endl;
cout << "Next Date: " << tomorrow.print_Day() << endl;
cout << "Previous Date: " << yesterday.print_Day() << endl;
system("pause");
return 0;
}
Header File (DateType.h)
#pragma once
#include <iostream>
#include <iomanip>
#include <string>
enum months { Jan=31, Feb = 28, March = 31, April = 30, May = 31,
June = 30, July = 31, August = 31, Sept = 30, Oct = 31, Nov = 30, Dec = 31, Feb_Leap = 29 };
class DateType {
private:
int mo;
int day;
int yr;
months DaysInMonth;
void Day_Month_Assign(); //This function does the same thing as DaysinMonth() on the assignment sheet, using the enum
public:
DateType(); //Constructor to set mo=0, day=0, yr=1000
void SetDate(int, int, int); //Date is set according to the incoming parameter
void NextDay(); //Date is increased by one to get NextDay
void PreviousDay(); //Date is decreased by one day to get Previous Day
string print_Day(); //Returns a string value
bool valid_date(); //Checks if an input is a valid date
};
DateType.cpp File
#include <iostream>
#include <cstdlib>
#include "DateType.h"
#include <string>
using namespace std;
DateType::DateType() {
mo = 0;
day = 0;
yr = 1000;
}
void DateType::Day_Month_Assign() {
switch (mo) {
case 1: DaysInMonth = Jan;
case 2: DaysInMonth = Feb;
case 3: DaysInMonth = March;
case 4: DaysInMonth = April;
case 5: DaysInMonth = May;
case 6: DaysInMonth = June;
case 7: DaysInMonth = July;
case 8: DaysInMonth = August;
case 9: DaysInMonth = Sept;
case 10: DaysInMonth = Oct;
case 11: DaysInMonth = Nov;
case 12: DaysInMonth = Dec;
}
if ((yr % 4 == 0 && yr % 100 != 0) ||
(yr % 400 == 0))
DaysInMonth = Feb_Leap;
}
void DateType::SetDate(int month, int days, int year) {
mo = month;
day = days;
yr = year;
Day_Month_Assign();
}
void DateType::NextDay() {
day++;
if (day > DaysInMonth) { //Raises month
day = 1;
mo++;
Day_Month_Assign(); //Assigns new value to enum
}
if (mo > 12) {
mo = 1;
yr++;
Day_Month_Assign();
}
}
void DateType::PreviousDay() {
day--;
//Different order than the last one
//I need to get the days in month from enum first
//That will be the new day value
if (day == 0) {
mo--;
Day_Month_Assign();
day = DaysInMonth;
}
if (mo == 0) {
yr--;
mo = 12;
Day_Month_Assign();
day = DaysInMonth;
}
}
string DateType::print_Day() {
string date;
date = (to_string(mo) + "-" + to_string(day) + "-" + to_string(yr));
return date;
}
bool DateType::valid_date() {
bool flag;
if (day <= DaysInMonth && day >= 1) { //Days in Month Check
if (mo > 0 && mo <= 12) { //Month in Year Check
flag = true;
cout << "Valid Date, Accepted!\n";
}
else {
flag = false;
cout << "Invalid Month!\n";
}
}
else {
flag = false;
cout << "Invalid Date!\n";
}
return flag;
}
Edit: The function in question is the String DateType::print_Day() function. Here are the errors:
Main File:
'print_Day' is not a member of 'DateType' (Called 3 Times), C2039
CPP File:
'print_Day' is not a member of 'DateType' (Line 73, C2039)
'mo': undeclared identifier (Line 75, C2065)
'day': undeclared identifier (Line 75, C2065)
'yr': undeclared identifier (Line 75, C2065)
declaration is incompatible with " DateType::print_Day()" (declared at line 21 of Header File) (Line 73, E0147)
Header File:
'print_Day': unknown override specifier (Line 21, C3646)
syntax error: '(' (Line 21, C2059)
unexpected token(s) preceding ';' (Line 21, C2238)
All three of the header file errors are thrown again later on in the error list. I hope this helps!
In DateType.h, string is not known because the string class belongs to std namespace. To fix the error, change the definition of print_Day to
std::string print_Day()
Do not try to fix it by adding using namespace std; in the header - that will cause no end of problems further down the line.
Small note on programming style: in DateType.cpp, it would be better to include DateType.h before anything else. That way, you will know that DateType.h has no dependencies and can be included in any cpp file.
This doesn’t address the question, but don’t name a variable flag. Give variables names that tell you what they do. In this case, date_is_valid, although a bit long, is much clearer. But you don’t need it. Just make the loop test while(!today.valid_date()).

How do I display the output of my C++ class

Hello guys I am trying to create a date class in C++ where it display the default date, displays a short set date, displays a long set date, just display a set year. However, I am trying this display the contents of the class when I input the data but I am getting an error "Use of undeclared identifier 'setDate'
Here is the header file code:
#ifndef dateClass_h
#define dateClass_h
using namespace std;
class DateObj
{
public:
int setDate(int month, int day, int year);
void shortDate(int month, int day, int year);
void longDate(string month, int day, int year);
//return the year
int getYear(int year){
return year;
}
private:
int month;
int day;
int year;
};
#endif /* dateClass_h */
Here is my implementation file code:
#include <stdio.h>
#include <iostream>
#include <string>
#include "dateClass.h"
using namespace std;
//setDate Method
int DateObj::setDate(int month, int day, int year){
//setMonth = month;
//day = setDay;
//year = setYear;
//check to make sure month is between 1 - 12.
if(month < 1 || month > 12){
cout << "This is an invalid Month. Please enter a month that is between 1 and 12: " << endl;
}
//check to make sure day is between 1 -31.
if(day < 1 || day > 31){
cout << "This is an invalid Day. Please enter a day that is between 1 and 31: " << endl;
}
//check to make sure year is greater than zero.
if(year < 0){
cout << "This is an invalid Year. Please enter a year that is greater than Zero" << endl;
}
return setDate(month,day,year);
}
And here is my main program code:
#include <iostream>
#include <string>
#include "dateClass.h"
using namespace std;
int main() {
DateObj myDate;
myDate.setDate(12, 25, 2016); //set the date to Dec 25, 2016.
cout << "The current date is: " << setDate() << endl;
return 0;
}
I will just like to know why I am getting this error and what I will need to fix in my class or main program.
Edit
I got the program to compile butI got the following error "EXC_BAD_ACCESS (code=2, address=0x7fff5f3fffe8) at the return setDate(month, day, year) break point.
#include <iostream>
#include <string>
#include "dateClass.h"
using namespace std;
int main() {
DateObj myDate;
myDate.setDate(12,25,2016); //set the date to Dec 25, 2016.
cout << "The current date is: " << myDate.setDate(12, 25, 2016) << endl;
return 0;
}
There appears to be no implementation for your shortDate function.
You have it in your header file, but you don't appear to have it in your dateClass.cpp file. You need to implement it in your dateClass.cpp file similar to how you did for setDate.
You're getting the error because it can't find any implementation.
The reason you are getting an error is because setDate() is a void function. When you try to use setDate() in the line:
cout << "The current date is: " << setDate() << endl;
you get an error because setDate() needs to return an std::ostream & object or some other data that is convertible. I recommend using setDate(int month, int day, int year) purely to set the data members of your class and create a separate function to actually print out the values.
As an alternative, you could overload setDate() so that it returns an acceptable data type, like so:
#include <iomanip>
//the parameter 'right' is required for chaining together different << when forming output
std::ostream & DateObj::setDate(std::ostream & right) {
//displays the date in mm/dd/yyyy format
//setfill defines a character to fill empty spaces created by setw
right << std::setfill('0') << std::setw(2) << month
<< '/' << std::setfill('0') << std::setw(2) << day
<< '/' << std::setfill('0') << std::setw(4) << year;
return right;
}
Well, for one thing you're calling setDate() inside setDate() in such a way that it will infinitely just call itself. You'll call setDate(), which will call setDate(), which will call setDate() and so on. I'm kind of a noob too, but I'm pretty sure what you're getting is a stack overflow error (Hey, title drop! :D). A stack overflow happens when you allocate too many variables and run out of memory. So because you're calling setDate() infinitely, you are also making infinite versions of the variables in it, and filling up all your memory.
For another, set date doesn't currently actually do anything. It checks to see if you have valid input, then calls itself again. From the name, I assume it's meant to populate your member variables? If that's what it's supposed to do, it should probably look more like this:
int DateObj::setDate(int month, int day, int year){
//check to make sure month is between 1 - 12.
if(month < 1 || month > 12){
cout << "This is an invalid Month. Please enter a month that is between 1 and 12: " << endl;
}
//check to make sure day is between 1 -31.
if(day < 1 || day > 31){
cout << "This is an invalid Day. Please enter a day that is between 1 and 31: " << endl;
}
//check to make sure year is greater than zero.
if(year < 0){
cout << "This is an invalid Year. Please enter a year that is greater than Zero" << endl;
}
//the part that actually sets the variables. Aka, the important bit.
month_ = month;
day_ = day;
year_ = year
}
The trailing underscores on month, day and year are just style things, I like to use them for member data so that I can use those names again as local variables in my functions, which was useful here if you noticed. Once you've put the data into your variables, it should be pretty easy to display everything. Just do something like:
cout << month_ << "/" << day_ << "/" << year_ << endl;
That will output your date to the console in a format something like this: 3/12/2016.

C++ assigning string variables in if statements

I am new to C++. I am trying to assign a string to a month depending on the number chosen in cin.
This is my code within a function.
cout << "Enter your birth month: ";
cin >> mm; //Birth Month//
int mm;
std::string month;
if(mm == 5 || mm == 05){
std::string month = "May";
}
// If month is equal to 5 or 05, set string variable month to May
cout << "You were born in the month of " << month << endl;
How do i assign the variable "month" to "may" if mm is equal to 5?
Your string variable is actually shadowed by another declaration in the if block scope
if(mm == 5 || mm == 05) {
std::string month = "May"; // That value is gone after the `}`
}
You probably want to write
if(mm == 5) {
month = "May"; // Note the type declaration is omitted here
}
Also note that why I ommitted mm == 05 in my sample above, is bacause
if(mm == 5 || mm == 05)
is wrong. The second comparison expression actually compares with an octal integer literal, and you certainly don't want to do this.
if(mm == 5)
is sufficient.
You already declared your string above, so a simple assignment operation on month would work:
if(mm == 5 || mm == 05){
month = "May";
}
Also, even if the user enters "05" as their integer, it will be stored as '5', so there is no need for the condition
|| mm == 05
Side note, you must declare "int mm" before your cin statement, like this:
int mm;
cout << "Enter your birth month: ";
cin >> mm; //Birth Month//
month = "May";
This is an assignment.
std::string month = "May";
This is not an assignment. This us a declaration. You are declaring a new variable called month, unrelated to any other variable by the same name you might have.