I am attempting to write code that checks the validity of a date [day and month only], inputs that date [day and month] into a "Date" structure, and then, finally, checks that the code in fact did what I expected it to do in a test function, by printing "SUCCESS" if successful, or "FAILURE" if not;
I have tried everything, and cannot think of what the problem might be; I am getting no warnings, so debugger didnt help. the code compiles and runs, however, there is nothing being printed on screen to let me know if it is actually working or not;
Any feedback would be greatly appreciated, thank you!
#include <stdio.h>
#include <stdlib.h>
#include "PatientData.h"
#define INVALID -100
#define SUCCESS 0
int main()
{
int datechecker(int month, int day) {
int ret = SUCCESS;
month = 2;
day = 2;
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8
|| month == 10 || month == 12)
{
if(!(day >= 1 && day <= 31))
ret = INVALID;
}
else if (month == 4 || month == 6 || month == 9 || month == 11)
{
if(!(day >= 1 && day < 31 ))
ret = INVALID;
}
else
{
ret = INVALID;
}
return(ret);
}
Date CreateDate(int day, int month)
{
Date date;
int ret = datechecker(2,2);
if (ret == SUCCESS)
{
date.Day = day;
date.Month = month;
}
else
{
date.Day = INVALID;
}
return date;
}
void CreateDateTest ()
{
Date date = CreateDate(2,2);
if (date.Day == 2)
{
printf("PASSED");
}
else
{
printf("FAILED");
}
}
return 0;
}
Well, you have three functions defined inside main, called CreateDate, CreateDateTest, and datechecker. However, the lone executable statement inside main is return 0, which is what your program is faithfully doing.
Your code cannot be run as such since PatientData.h is not available, but I suspect it will work once you call CreateDateTest from main.
Related
i'm doing a program in c that needs to have random dates that have to be valid and after the current date. For the generation there aren't any problems at all. The only thing i can't do is to accept only the up to date dates.
I've already tried to firstly check if the date is valid and then to check if is greater than current date. Then i've tried to do the opposite but any of these solutions didn't worked.
This is the function that checks the date:
short dateControl( const unsigned short day, const unsigned short month, const unsigned short year, const int min_year, const int max_year, struct tm curTime)
{
short correct = ZERO;
if( (year >= curTime.tm_year) && (year <= max_year) ){
if( (month >= 1) && (month <= 12) ){
if( (day >= 1 && day <= 31) && (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) ){
correct = ONE;
}else if( (day >= 1 && day <= 30) && (month == 4 || month == 6 || month == 9 || month == 11) ){
correct = ONE;
}else if( (day >= 1 && day <= 28) && (month == 2) ){
correct = ONE;
}else if( day == 29 && month == 2 && (year % 400 == 0 ||(year % 4 == 0 && year % 100 != 0)) ){
correct = ONE;
}else{
correct = ZERO;
}
} else{
correct = ZERO;
}
}else{
correct = ZERO;
}
if(correct == ONE){
if( year > curTime.tm_year ){
correct = ONE;
}else if( year == curTime.tm_year ){
if( month > curTime.tm_mon ){
correct = ONE;
}else if( month == curTime.tm_mon ){
if( day > curTime.tm_mday ){
correct = ONE;
}else if(day == curTime.tm_mday){
correct = ZERO;
}else if(day < curTime.tm_mday){
correct = ZERO;
}
}else if( month < curTime.tm_mon ){
correct = ZERO;
}
}
}
}
return correct;
}
This is the part where the date is generated
day = random_int(1, 31);
month = random_int(1, 12);
year = random_int(local->tm_year, local->tm_year + 1);
validDate = dateControl(tempTrip.dep_date.day, tempTrip.dep_date.month, tempTrip.dep_date.year, local->tm_year, (local->tm_year + 1), *local);
while(validDate == ZERO){
tempDriver.sub_date.day = random_int(1, 31);
tempDriver.sub_date.month = random_int(1, 12);
tempDriver.sub_date.year = random_int(local->tm_year, (local->tm_year + 1));
validDate = dateControl(tempTrip.dep_date.day, tempTrip.dep_date.month, tempTrip.dep_date.year, local->tm_year, (local->tm_year + 1), *local);
}
}
I expect that if the generated date is 2/7/2019 and today is the 18/8/2019, the generated date needs to be discarded and another needs to be generated.
i'm doing a program in c that needs to have random dates that have to be valid and after the current date. For the generation there aren't any problems at all. The only thing i can't do is to accept only the up to date dates.
The fact that you need to determine if the date is/isn't valid indicates that the way you're generating random dates is a problem.
Specifically, if you get the current time (using time()) and add a random positive value to it (while being careful to avoid overflow), and then convert the result into a date (e.g. using gmtime()); then you can guarantee that the random dates are valid and in the future without doing any checking and you can delete all of your dateControl() code.
So I created a program where you have to enter a date dd/mm/yyyy and then you get date.day + 1 , but I wan't to verify that the date entered is valid, that is date.day between 1 and 31, month between 1 and 12 and year between 1 and 9999, and that day entered is less than the number of days of that month, if one of these fails return exit failure
`// Program to determine tomorrow's date
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
struct date
{
int day;
int month;
int year;
};
int main(void)
{
struct date today, nextDay;
bool isValidDate(struct date VarName);
struct date dateUpdate(struct date today);
printf("Enter today's date (dd mm yyyy): ");
scanf("%i %i %i", &today.day, &today.month, &today.year);
if (isValidDate(today) == false)
{
printf("Invalid date format. \n");
exit(EXIT_FAILURE);
}
nextDay = dateUpdate(today);
printf("Tomorrow's date is: %i/%i/%i \n", nextDay.day,
nextDay.month,
nextDay.year % 100);
return 0;
}
// Function to update today's date to tomorrow's date
struct date dateUpdate(struct date today)
{
struct date tomorrow;
int numberOfDays(struct date VarName);
if (today.day != numberOfDays(today)) // End of day
{
tomorrow.day = today.day + 1;
tomorrow.month = today.month;
tomorrow.year = today.year;
}
else if (today.month == 12) // End of year
{
tomorrow.day = 1;
tomorrow.month = 1;
tomorrow.year = today.year + 1;
}
else // End of month
{
tomorrow.day = 1;
tomorrow.month = today.month + 1;
tomorrow.year = today.year;
}
return tomorrow;
}
// Function to find the numbers of days in a month
int numberOfDays(struct date VarName)
{
const int daysPerMonth[13] = {0, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31
};
int days;
bool isLeapYear(struct date VarName);
bool isValidDate(struct date VarName);
if (isLeapYear(VarName) == true && VarName.month == 2)
{
days = 29;
}
else
{
days = daysPerMonth[VarName.month];
}
return days;
}
// Function to determine if a year is a leap year
bool isLeapYear(struct date VarName)
{
bool leapYearFlag;
if ((VarName.year % 4 == 0 && VarName.year % 100 != 0) ||
VarName.year % 400 == 0)
{
leapYearFlag = true; // It's a leap year
}
else
{
leapYearFlag = false; // Not a leap year
}
return leapYearFlag;
}
bool isValidDate(struct date VarName)
{
if ( (VarName.day < 1 && VarName.day > 31) || (VarName.day >
numberOfDays(VarName)) ) // Day format verifier
{
return false;
}
else if (VarName.month < 1 && VarName.month > 12)
// Month format verifier
{
return false;
}
else if (VarName.year < 1 && VarName.year > 9999)
// Year format verifier
{
return false;
}
else
{
return true;
}
}`
TEST A
Enter today's date (dd mm yyyy): 31 13 2018
RESULT
prog_8.4.c:78:16: runtime error: index 13 out of bounds for type 'const int [13]'
Invalid date format.
TEST B
Enter today's date (dd mm yyyy): 31 2 2018
RESULT
Invalid date format.
TEST C
Enter today's date (dd mm yyyy): 31 12 2018
RESULT
Tomorrow's date is: 1/1/19
if you notice, if there's a month that's greater than 13 I get a runtime error, which I don't want to get, I wan't to get the same message as test B where the day entered is greater than the days of that month, if I have my format verifier before the DateUpdate function why does the compiler runs the DateUpdate function, because I think that A error is related to this function, but if my error verifier worked correctly the program wouldn't run this function because it would terminate before it gets there, at least that's what I think, can you help me out here please?
I guess the problem lies in here:
if ( (VarName.day < 1 && VarName.day > 31) || (VarName.day >
numberOfDays(VarName)) ) // Day format verifier
As you see in the below, there is no index for 13 in const in daysPerMonth[13]. You only have index from 0 to 12, and in function bool isValidDate(), you put the Varname without checking whether the index is between 1 to 12.
Checking the index before putting Varname inside numberOfDays() will fix your problem.
I have a little problem with my code. I need to check if user's given date is valid or not. I want to check it using 2 rules:
1. Date is valid date and found in a calendar (for example 29.2.2015 is invalid because there's only 28 days in February 2015) 2. Day and month can only be max 2 numbers (for example day 10 and 02 are valid but 010 and 002 are not). All help is appreciated!
This is my code this far:
void dateValidator(const char *date1) {
struct tm date = {0};
int day1;
int month1;
int year1;
int vday;
int vmonth;
int vyear;
sscanf(date1, "%3d.%3d.%d",&day1,&month1,&year1);
/**How do I check that if sscanf reads more than 2 characters on month and day, date is
invalid?**/
date.tm_year = year1 - 1900;
date.tm_mon = month1 - 1;
date.tm_mday = day1;
date.tm_isdst = -1;
vday = date.tm_mday;
vmonth = date.tm_mon;
vyear = date.tm_year;
mktime(&pvm);
if ((vday != date.tm_mday) || (vmonth != date.tm_mon) || (vyear != date.tm_year)) {
/**This doesnt seem to work**/
printf("Invalid date");
}
}
I have deleted my previous answer and posting another one. Actually your code is fine, You just have to send the correct parameter to mktime and to check its return value. I.e. change:
mktime(&pvm);
if ((vday != date.tm_mday) || (vmonth != date.tm_mon) || (vyear != date.tm_year)) {
/**This doesnt seem to work**/
printf("Invalid date");
}
to something like:
r = mktime(&date);
if (r == -1 || (vday != date.tm_mday) || (vmonth != date.tm_mon) || (vyear != date.tm_year)) {
printf("Invalid date");
}
and declare the variable r as time_t r;.
int IsValidDate(int year, int month, int day)
{
unsigned int leap;
unsigned char mon_day[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
/* check the rang of the year */
if ((year < 1) || (year >= 3200))
{
return 0;
}
if ((month < 1) || (month > 12))
{
return 0;
}
/* if it's leep year */
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
{
leap = 1;
}
else
{
leap = 0;
}
mon_day[1] += leap;
if ((day > mon_day[month - 1]) || (day < 1))
{
return 0;
}
return 1;
}
For ruler 1, I have wrote this code for check the date before.
And I hope this code can help you.
The ruler 2 can easily checked, you can check it by format the valid date and compare it with the input string.
How do I check that if sscanf reads more than 2 characters on month and day, date is invalid?
Day and month can only be max 2 numbers digits (for example day 10 and 02 are valid but 010 and 002 are not).
An easy check: Record the offset at the end of the scan and tests 1) that it is not the original 0 (scanning got that far) and 2) this is the end of the string so as to detect extra junk in data1[]. Change 3d to 2d.
int n = 0;
sscanf(date1, "%2d.%2d.%d %n",&day1,&month1,&year1, &n);
if (n > 0 && data1[n] == '\0') Success();
else Fail();
Pedantic code would check with "%[]" to disallow leading spaces and '+'.
int n = 0;
sscanf(date1, "%*2[0-9].%*2[0-9].%*4[0-9] %n", &n);
if (n == 0 || data1[n]) Fail();
else {
sscanf(date1, "%2d.%2d.%d",&day1,&month1,&year1);
...
How to check if date is valid using mktime?
#Marian posted a good solution which adds a test of the return value of mktime().
if (-1 == mktime(&data)) Fail();
if (vday != date.tm_mday) || (vmonth != date.tm_mon) || (vyear != date.tm_year) Fail();
This is a section of a problem I'm working on. The leap year part is not returning correctly. It returns 29 for February whether I put in a leap year or not. What am I doing wrong?
#include <stdio.h>
#include <stdbool.h>
struct date
{
int month;
int day;
int year;
};
int main (void)
{
struct date now;
void numberOfDays (struct date v);
bool findLeap (struct date v);
printf("Enter the date in this format mm/dd/yyyy: ");
scanf("%i", &now.month, &now.day, &now.year);
numberOfDays(now);
return 0;
}
void numberOfDays (struct date v)
{
int daysOfMonth;
bool findLeap (struct date v);
if (v.month == 4 || v.month == 6 || v.month == 9 || v.month == 11)
daysOfMonth = 30;
else if (v.month == 2)
{
findLeap(v);
if (findLeap)
daysOfMonth = 29;
else
daysOfMonth = 28;
}
else
daysOfMonth = 31;
printf("Number of days in month: %i", daysOfMonth);
}
bool findLeap (struct date v)
{
bool isLeap;
if ( v.year % 4 == 0 && v.year % 100 != 0 || v.year % 400 == 0)
{
isLeap = true;
}
else
{
isLeap = false;
}
return isLeap;
}
findLeap(v);
if (findLeap)
The above doesn't branch on the return value of findLeap, it's always true. It's like that, because function identifiers implicitly convert to function pointers, and when checked against in a conditional, will just evaluate to true.
So just write it correctly:
if (findLeap(v))
Oh, and might I suggest a better name? Since the functions purpose is to answer a query, I think it should have a name that reads like one. I'd go for isLeapYear.
I am writing a program that involves checking the validity of a date. I have set the conditions for the months which have 31 days in them, and I have set the conditions for the months which have 30 days in them. I left out February because there are issues with leap year.
When I run the program, it is able to print "SUCCESS" on the screen for all valid dates. However, when I try to enter an invalid date, the program fails to write "FAILURE" on the screen, as I have it set to do [at least I believe].
What is wrong with the code here?
#include <stdio.h>
int main ()
{
int month = 1;
int day = 32;
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8
|| month == 10 || month == 12)
{
if (0 < day && day < 32)
{
return printf("%s","SUCCESS");
}
}
else if (month == 4 || month == 6 || month == 9 || month == 11)
{
if (0 < day && day < 31 )
{
return printf("%s","SUCCESS");
}
}
else
{
return printf("%s","FAILURE");
}
return 1;
}
Your code have a wrong flow and #JoshStir is right about it.
I may know when you enter in a conditional statement, the other conditionals in the same level are ignored.
You test guide your code to enter in your first condicional.
int month = 1;
int day = 32;
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8
|| month == 10 || month == 12)
{
//--> Flow pass through here ( cause month == 1 )
if (0 < day && day < 32)
{
//Flow DON'T pass through here ( cause day == 32)
return printf("%s","SUCCESS");
}
}
else if (month == 4 || month == 6 || month == 9 || month == 11)
{
//--> Flow DON'T pass through here ( cause flow ENTERER FIRST IF STATEMENT BEFORE)
if (0 < day && day < 31 )
{
return printf("%s","SUCCESS");
}
}
else
{
//--> Flow DON'T pass through here ( cause flow ENTERED FIRST IF STATEMENT BEFORE)
return printf("%s","FAILURE");
}
I advice you to review your code.
Try rethink and considerate what did #JoshStir advice you too.
Maybe using months and days in same comparation operation a good idea.
We were all new once, so I'll try to answer your question as clearly as I can. Given your test data:
int month = 1;
int day = 32;
your code will enter the first if statement (as month == 1)
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8
|| month == 10 || month == 12)
It will then check against the inner if statement (is day > 0 and < 32?)
if (0 < day && day < 32)
day == 32, so it will not enter the if and print "SUCCESS", it will exit the if and then exit the application. If you want the data above to enter the failure condition, you would want something somewhat like the following:
if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8|| month == 10 || month == 12) && (day > 0 && day < 32))