Related
For example in input.txt file there is date 20210405. Date is in rrrrmmdd format without any '/' or '.'. How do you check if date is in correct format not in 20211405?.
My code works only for numbers that dont have zero in day for example 05,07,08, my code works only for 10 or 11. How do I fix that?
int main() {
char load[50];
long year, day, month;
int lenght, lenght2, lenght3;
int i = 0;
FILE *file;
file = fopen("input.txt", "r");
while (fgets(load, sizeof load, file) != NULL) {
if (i == 0) {
if (strlen(load) == 8) {
year = strtol(load, NULL, 10);
month = year;
day = year;
year = year * 0.0001;
lenght = (log10(abs(year))) + 1;
if (lenght == 4) {
day = day % 100;
lenght2 = (log10(abs(day))) + 1;
if (lenght2 == 2 && day <=31) {
month = (month % 10000) - 30;
month = month / 100;
lenght3 = (log10(abs(day))) + 1;
if (month <= 12 && lenght2 == 2) {
printf("Datum: %s", load);
} else {
printf("Invalid input.");
}
} else {
printf("Invalid input.");
}
} else {
printf("Invalid input.");
}
} else {
printf("Invalid input.");
}
}
}
}
You have a few flaws in your code:
fgets includes a \n at the end of your string if it is found in the file. Unless you read the last line where no more \n is present, you will get 9 characters in your buffer.
Your condition if (strlen(load) == 8) will fail in the other cases.
You should not use floating point operations on integers.
year = year * 0.0001; In best case it is identical to year = year / 10000;, in worst case you get some rounding errors.
You check the "length" of the value for day and month by taking log10. That means that the numerical value must be >10 to get a length of 2. That is exactly what you are complaining about.
A proper check for valid valued would be to check whether the numerical value is in proper range.
For some reason to reduce month by 30. That doesn't really make much sense.
You don't use variable i at all. The corresponding if (i==0) is rather useless.
A fixed version could look like this:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main(void) {
char load[50];
long year, day, month;
bool valid = false;
FILE* file = fopen("input.txt", "r");
// TODO: Check for NULL
while (fgets(load, sizeof load, file) != NULL) {
// Remove trailing '\n'
int len = strlen(load);
if (load[len-1] == '\n') {
load[len-1] = 0;
}
// Do we have exactly 8 digits?
if (strlen(load) == 8) {
long value = strtol(load, NULL, 10);
year = value / 10000;
month = (value / 100) % 100;
day = value % 100;
if (year >= 1000) {
if (day > 0 && day <= 31) {
if (month > 0 && month <= 12) {
valid = true;
}
}
}
}
if (valid) {
printf("Datum: %s", load);
}
else {
printf("Invalid input.");
}
}
}
}
It is a bad idea to use floating point arithmetics to split the value into the year, month and day parts. The main reason for this is floating point numbers are represented internally in base 2 so 0.0001 is not represented exactly, so converting the multiplication result to long may cause truncation of the value.
You should instead use integer arithmetics this way:
long value = strtol(load, NULL, 10);
year = value / 10000;
month = (value / 100) % 100;
day = value % 100;
You could also use sscanf() to parse the line directly into 3 int values:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main() {
char load[50];
int year, day, month;
int i = 0;
FILE *file = fopen("input.txt", "r");
if (file == NULL) {
fprintf(stderr, "cannot open input.txt: %s\n", strerror(errno));
return 1;
}
while (fgets(load, sizeof load, file) != NULL) {
if (i++ == 0) {
static const int mlen[] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
char c[2];
/* accept up to 4 bytes for year, 2 for month, 2 for day and check for a trailing newline */
if (sscanf(load, "%4d%2d%2d%1[\n]", &year, &month, &day, c) != 4) {
fprintf(stderr, "invalid date line: %s", load);
break;
}
if (year < 1901 || year > 2099
|| month < 1 || month > 12
|| day < 1 || day > mlen[month]
|| (day == 29 && month == 2 && year % 4 != 0)) {
fprintf(stderr, "invalid date: %d/%d/%d\n", day, month, year);
break;
}
printf("Datum: %s", load);
} else {
/* handle other lines */
...
}
}
fclose(file);
return 0;
}
Can we check the date input form dd-mm-yyyy and also check how many digits that users input? Example the users input 7-7-2000, is Invalid, it must be 07-07-2000.
This is my code.
int dateCheck(int argc, const char * argv[]){
int day;
int month;
int year;
int count = 0;
char inputValue[20];
printf("Enter date : ");
fgets(inputValue, sizeof(inputValue), stdin);
sscanf(inputValue, "%d-%d-%d",&day,&month,&year);
if ((year >= 1919) && (year <= 2119)) {
if ((month >= 1) && (month <= 12)) {
if ( ((day >= 1) && (day <= 31)) && ((month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 9) || (month == 11)) ) {
printf("Valid.\n");
}
else if ( ((day >= 1) && (day <= 30)) && ((month == 4) || (month == 6) || (month == 8) || (month == 10) || (month == 12)) ){
printf("Valid.\n");
}
else if ( ((day >= 1) && (day <= 28)) && (month == 2) ){
printf("Valid.\n");
}
else if ( (day == 29) && (month == 2) && ( (year%400 == 0) || ((year%4 == 0) && (year%100 != 0)) ) ){
printf("Valid.\n");
}
else{
printf("Invalid.\n");
}
}
else{
printf("Invalid.\n");
}
}
else{
printf("Invalid.\n");
}
Can we check the date input form dd-mm-yyyy and also check how many digits that users input?
Sure, how about using some helper functions?
Divide the task in conceptual parts and write code for each. Divide and conquer.
// return 0: fail
// return 1: success
static int scan_int(int *dest, const char *s, int min, int max, int digits,
char endchar) {
*dest = 0;
for (int i = 0; i < digits; i++) {
if (*s < '0' || *s > '9')
return 0;
*dest = *dest * 10 + *s - '0';
s++;
}
return *dest >= min && *dest <= max && *s == endchar;
}
static int isleapyear(int year) {
if (year % 4) return 0;
if (year > 1582) { // see https://en.wikipedia.org/wiki/Gregorian_calendar
if (year % 100 == 0 && year % 400) return 0;
}
return 1;
}
static int eom(int year, int month) {
static char eoms[1 + 12] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (month != 2) {
return eoms[month];
}
return eoms[month] + isleapyear(year);
}
Now armed with some helper functions, the task is directly coded.
// dd-mm-yyyy
#define YEAR_MIN 1919
#define YEAR_MAX 2019
int dateCheck(void) {
int day, month, year;
char inputValue[20] = {0};
printf("Enter date : ");
fgets(inputValue, sizeof inputValue, stdin);
if (scan_int(&year, &inputValue[3 + 3], YEAR_MIN, YEAR_MAX, 4, '\0')
&& scan_int(&month, &inputValue[3], 1, 12, 2, '-')
&& scan_int(&day, inputValue, 1, eom(year, month), 2, '-')) {
printf("Valid. %02d-%02d-%04d\n", day, month, year);
return 1;
}
printf("Invalid.\n");
return 0;
}
Nifty trick: Code validates day after fetching a valid year, month.
Unless you are prohibited from using the functions provided in string.h, they can make you date check a bit easier. For example, you can verify that only allowable characters are present in the input using strchr(). You can also use strchr() to locate each '-' when checking that each dd mm yyyy group is the correct number of characters. You can use strlen() to verify the final yyyy group is 4-characters, and you can use strcspn() to trim the trailing '\n' at the end of any input read using fgets(). The rest is simple ariithmetic.
For example, you could write a chkdate(const char *s) function to check that the string s is in your desired format, returning 1 if it is, or 0 otherwise, e.g.:
#define DATEGRP 3 /* if you need a constant, #define one (or more) */
#define DATELN 10
#define DATEC 128
/* check if given date format is dd-mm-yyyy
* returns 1 on success, zero otherwise
*/
int chkdate (const char *s)
{
const char *datechars = "-0123456789", /* valid characters */
*p = s, /* pointer & end-pointer */
*ep = p;
size_t group = 0; /* group counter, dd mm yyyy */
int groups[] = { 2, 2, 4 }; /* req'd chars per group */
for (int i = 0; s[i]; i++) /* verify only datechars in s */
if (!strchr (datechars, s[i]))
return 0;
/* loop over dd mm groups using strchr to locate '-' */
while (group < DATEGRP - 1 && (ep = strchr(p, *datechars))) {
if ((ep - p) != groups[group]) /* verify correct no. of chars */
return 0;
p = ++ep; /* update p to following char */
group++; /* increment groups counter */
}
/* check chars in final group and all digits */
if (strlen (p) != (size_t)groups[group] || strchr (p, '-'))
return 0;
return 1; /* if you made it here, valid date, return 1 */
}
You can also make a trivial solution using sscanf alone, that behaves in the exact same manner simply by using a proper format string with appropriate field-width modifiers on each integer conversion checking the return of sscanf against 3, except the sscanf trivial solution will fail for any case where yyyy begins with an integer and then contains an invalid character) e.g.
int chkdate (const char *s)
{
int d, m ,y;
return sscanf (s, "%2d-%2d-%4d", &d, &m, &y) == 3;
}
Adding the required headers and a short example program that will validate user input using the function above you could do:
#include <stdio.h>
#include <string.h>
#define DATEGRP 3 /* if you need a constant, #define one (or more) */
#define DATELN 10
#define DATEC 128
/* check if given date format is dd-mm-yyyy
* returns 1 on success, zero otherwise
*/
int chkdate (const char *s)
{
const char *datechars = "-0123456789", /* valid characters */
*p = s, /* pointer & end-pointer */
*ep = p;
size_t group = 0; /* group counter, dd mm yyyy */
int groups[] = { 2, 2, 4 }; /* req'd chars per group */
for (int i = 0; s[i]; i++) /* verify only datechars in s */
if (!strchr (datechars, s[i]))
return 0;
/* loop over dd mm groups using strchr to locate '-' */
while (group < DATEGRP - 1 && (ep = strchr(p, *datechars))) {
if ((ep - p) != groups[group]) /* verify correct no. of chars */
return 0;
p = ++ep; /* update p to following char */
group++; /* increment groups counter */
}
/* check chars in final group and all digits */
if (strlen (p) != (size_t)groups[group] || strchr (p, '-'))
return 0;
return 1; /* if you made it here, valid date, return 1 */
}
int main (void) {
char buf[DATEC] = "";
size_t len;
fputs ("enter date (dd-mm-yyyy): ", stdout); /* prompt */
if (!fgets (buf, DATEC, stdin)) { /* read/validate input */
fputs ("(user canceled input)\n", stderr);
return 1;
}
buf[(len = strcspn(buf, "\n"))] = 0; /* trim trailing '\n', save len */
if (len != DATELN) { /* if not DATELN chars, invalid */
fputs ("error: invalid date format,\n", stderr);
return 1;
}
if (chkdate (buf)) /* check dd-mm-yyyy format */
puts ("date is valid");
else /* otherwise, invalid format */
fputs ("date is invalid.\n", stderr);
}
Example Use/Output
Wrong number of digits:
$ ./bin/chkdate
enter date (dd-mm-yyyy): 7-7-2000
error: invalid date format,
Invalid character 'a' included:
$ ./bin/chkdate
enter date (dd-mm-yyyy): 07-7a-2000
date is invalid.
Good date:
$ ./bin/chkdate
enter date (dd-mm-yyyy): 07-07-2000
date is valid
There are literally dozens of ways to approach this with many combinations of loops, counters, pointers, character classification, etc... There isn't any "right" way, so long as it is reasonably efficient and does the validation. So experiment, write it several different ways and choose the one that is most readable and understandable to you.
Here you can first take in the string, check it's format and then extract individual digits from the string.
#include<stdio.h>
#include<string.h>
void checkDate(){
char str[20];
printf("%s","Enter date : ");
fgets(str, sizeof(str), stdin);
//char str[11] = "32-02-2019";
int d1=str[0]-48; //Convert the ascii digits to integers
int d2=str[1]-48;
int day=d1*10+d2;
int m1=str[3]-48;
int m2=str[4]-48;
int month=m1*10+m2;
int y1=str[6]-48;
int y2=str[7]-48;
int y3=str[8]-48;
int y4=str[9]-48;
int year=y1*1000+y2*100+y3*10+y4;
int format_validity=0;
printf("stringLen:%ld\n",strlen(str));
if(strlen(str)==11){ //check length of the string
if(str[2]=='-' && str[5]=='-'){ //check the separator positions
if((d1>=0 && d1<=9) && (d2>=0 && d2<=9)){ //check digits are in range 0-9
if((m1>=0 && m1<=9) && (m2>=0 && m2<=9)){ //check digits are in range 0-9
if((y1>=0 && y1<=9) && (y2>=0 && y2<=9) && (y3>=0 && y3<=9) && (y4>=0 && y4<=9)){ //check the digit are in range 0-9
format_validity=1; //mark the format valid
}
}
}
}
}//else the format is invalid
if(format_validity){
//Your Code from here
if ((year >= 1919) && (year <= 2119)) {
if ((month >= 1) && (month <= 12)) {
if (((day >= 1) && (day <= 31)) && ((month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 9) || (month == 11)) ) {
printf("Valid.\n");
}
else if ( ((day >= 1) && (day <= 30)) && ((month == 4) || (month == 6) || (month == 8) || (month == 10) || (month == 12)) ){
printf("Valid.\n");
}
else if ( ((day >= 1) && (day <= 28)) && (month == 2) ){
printf("Valid.\n");
}
else if ( (day == 29) && (month == 2) && ( (year%400 == 0) || ((year%4 == 0) && (year%100 != 0)) ) ){
printf("Valid.\n");
}
else{
printf("Invalid.\n");
}
}
else{
printf("Invalid.\n");
}
}
else{
printf("Invalid.\n");
}
}else printf("Invalid format.\n");
printf("day:%d, month:%d, year:%d",d1*10+d2,m1*10+m2,year);
}
int main(){
checkDate();
return 0;
}
Test:
[1]
Enter date : 29-02-2019
stringLen:11
Invalid.
day:29, month:2, year:2019
[2]
Enter date : 29-02-2020
stringLen:11
Valid.
day:29, month:2, year:2020
[3]
Enter date : a0-03-2020
stringLen:11
Invalid format.
day:490, month:3, year:2020
[4]
Enter date : 12-2-2019
stringLen:10
Invalid format.
day:12, month:17, year:152
So i have this simple code that i've found here. I want to make it work in a loop. I've tried couple of times with diffrent methods but output is bad. Working in Ubuntu Visual Studio
EDIT I've added if(y>=2015 && y<=3000) and it is working properly?
EDIT 2 I've modified my code and followed #Sergey advice... It is still not working properly...
I've tried to add "Check return value of scanf" but it is also not working.
if ((scanf("%u", &d) == 1) && (scanf("%u", &m) == 1) && (scanf("%u", &y) == 1))
while (fdateCheck());
else
//...EOF or conversion failure...
while (fdateCheck());
or
while ((rc = scanf("%u.%u.%u", &d, &m, &y)) != EOF)
{
if (rc != 3)
//...oops data problems...
else
//...all OK...
}
Need advice about checking return of scanfs
int fdateCheck();
unsigned int d,m,y;
unsigned int daysinmonth[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int rc;
int legit = 0;
int main()
{
printf("Enter the date\n");
scanf("%u.%u.%u",&d,&m,&y);
while (fdateCheck());
}
int fdateCheck()
{
if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0))
{
daysinmonth[1]=29;
}
else if (y >= 2015 && y <= 3000)
{
if (m < 13)
{
if (d <= daysinmonth[m-1])
legit = 1;
}
if (legit == 1)
{
system("clear");
printf("It is a legitimate date!\n");
return 0;
}
}
else
system("clear");
int ch = fgetc(stdin);
if (ch == '\n')
{
system("clear");
printf("It's not a legitimate date!\n");
printf("\nRetry: ");
return 1;
}
fflush(stdin);
}
If you have an appropriate code in the function void main() and need to repeat it in a cycle as you describe you can do the following:
rename original void main() to int one_step()
put return 0; after printf("It is a legitimate date!\n");
put return 1; after printf("It's not a legitimate date!\n");
create the new void main() function as:
void main() {
while(one_step());
}
You do not need break; and return main();. You may need some enhancements as described in the comments above. Good luck in coding!
UPDATE #1
I meant such an improvement of your code:
#include <stdio.h>
#include <stdlib.h>
int fdateCheck();
int main()
{
while (fdateCheck());
}
int fdateCheck()
{
int res;
int legit = 0;
unsigned int d,m,y;
unsigned int daysinmonth[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// get input block
printf("Enter the date\n"); // prompt for data
res = scanf("%u.%u.%u",&d,&m,&y); // get input data
if (res == EOF) { // check if no more input
printf("Input error\n");
exit(1);
}
// check if input data is valid
if (res != 3) { // check if 3 numbers scanned
system("clear");
printf("It is not a date\n");
fflush(stdin);
return 1;
}
// make leap year correction
if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0)) {
daysinmonth[1]=29; // leap year correction
}
// check if year, month and day is valid
if (y >= 2015 && y <= 3000) { // check if year in this range
if (0 < m && m < 13) { // check if month in this range
if (0 < d && d <= daysinmonth[m-1]) // check if day in this range
legit = 1;
}
}
// print a message and finish the iteration
if (legit == 1) {
printf("It is a legitimate date!\n");
return 0;
}
else {
system("clear");
printf("It's not a legitimate date!\n");
printf("Please retry.\n");
fflush(stdin);
return 1;
}
}
I also moved all variables inside the function. This will restore values of legit and daysinmonth[1] before each iteration.
UPDATE #2
My next proposal:
#include <stdio.h>
#include <stdlib.h>
int fdateCheck();
int main()
{
while (fdateCheck());
}
int fdateCheck()
{
int res;
int legit = 0;
unsigned int d,m,y;
unsigned int daysinmonth[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// get input block
printf("Enter the date\n"); // prompt for data
res = scanf("%u.%u.%u",&d,&m,&y); // get input data
if (res == EOF) { // check if no more input
printf("Input error\n");
exit(1);
}
// check if input data is valid
if (res != 3) { // check if 3 numbers scanned
fgetc(stdin); // remove a barrier
system("clear");
printf("It is not a date\n");
fflush(stdin);
return 1;
}
// make leap year correction
if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0)) {
daysinmonth[1]=29; // leap year correction
}
// check if year, month and day is valid
if (y >= 2015 && y <= 3000) { // check if year in this range
if (0 < m && m < 13) { // check if month in this range
if (0 < d && d <= daysinmonth[m-1]) // check if day in this range
legit = 1;
}
}
// print a message and finish the iteration
if (legit == 1) {
printf("It is a legitimate date!\n");
return 0;
}
else {
system("clear");
printf("It's not a legitimate date!\n");
printf("Please retry.\n");
fflush(stdin);
return 1;
}
}
Below is a code I wrote for a dice game called cho han. To input your guess I've used number to represent the words 'odd' and 'even'. Since then I have tried to write it again, but to actually write odd or even in the scanf section, but can't get it to work. Any help would be appreciated :)
//cho-han
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand(time(NULL));
int x = (rand() % 6) + 1;
int y = (rand() % 6) + 1;
int result = 0;
int guess = 0;
printf("The values of two dice rolls will be added up. The aim is to guess whether that total number will be odd or even.\n");
printf("To guess odd, enter '1'. To guess even, enter '2'.\n\n");
printf("Please enter your guess for the combined total of the two dice rolls: ");
scanf_s("%d", &guess);
if (guess == 2)
{
printf("\nyour guess is even.\n");
}
if (guess == 1)
{
printf("\nyour guess is odd.\n");
}
if (guess > 2 || guess < 1)
{
printf("\nInvalid guess.\nYou lose!\n");
return (1);
}
printf("\ndice roll 1 = %d\n", x);
printf("dice roll 2 = %d\n", y);
result = x + y;
printf("\ncombined total of both rolls is %d", result);
if (result == 1 || result == 3 || result == 5 || result == 7 || result == 9 || result == 11)
{
printf("\ncombined total of both rolls is odd.\n");
}
else
{
printf("\ncombined total of both rolls is even.\n");
}
if (guess == 1 && result == 1 || guess == 1 && result == 3 || guess == 1 && result == 5 || guess == 1 && result == 7 || guess == 1 && result == 9 || guess == 1 && result == 11)
{
printf("\nYou win!\n");
}
else if (guess == 2 && result == 2 || guess == 2 && result == 4 || guess == 2 && result == 6 || guess == 2 && result == 8 || guess == 2 && result == 10 || guess == 2 && result == 12)
{
printf("\nYou win!\n");
}
else
{
printf("\nYou lose!\n");
}
return 0;
}
You should change scanf_s to scanf
The line if (result == 1 || result == 3 ... could be if (result % 2 == 1) {
You could use strcmp to solve your question
The following code could work:
//cho-han
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int main(void)
{
srand(time(NULL));
int x = (rand() % 6) + 1;
int y = (rand() % 6) + 1;
int result = 0;
int guess = 0;
char buf[10];
printf("The values of two dice rolls will be added up. The aim is to guess whether that total number will be odd or even.\n");
printf("To guess odd, enter 'odd'. To guess even, enter 'even'.\n\n");
printf("Please enter your guess for the combined total of the two dice rolls: ");
fgets(buf, sizeof buf, stdin);
if (strcmp(buf, "even\n") == 0) {
guess = 2;
printf("\nyour guess is even.\n");
} else if (strcmp(buf, "odd\n") == 0) {
guess = 1;
printf("\nyour guess is odd.\n");
} else {
printf("\nInvalid guess.\nYou lose!\n");
return 1;
}
printf("\ndice roll 1 = %d\n", x);
printf("dice roll 2 = %d\n", y);
printf("\ncombined total of both rolls is %d", x + y);
result = (x + y) % 2;
if (result == 1)
printf("\ncombined total of both rolls is odd.\n");
else
printf("\ncombined total of both rolls is even.\n");
if (guess == result)
printf("\nYou win!\n");
else
printf("\nYou lose!\n");
return 0;
}
You need to change your guess to char type and scanf to capture string.
char guess[256];
scanf("%s", guess);
And then the best way would be to call toupper() and compare with your text using strcmp().
I was asked to right a program which checks if the date entered by the user is legitimate or not in C. I tried writing it but I guess the logic isn't right.
//Legitimate date
#include <stdio.h>
void main()
{
int d,m,y,leap;
int legit = 0;
printf("Enter the date\n");
scanf("%i.%i.%i",&d,&m,&y);
if(y % 400 == 0 || (y % 100 != 0 && y % 4 == 0))
{leap=1;}
if (m<13)
{
if (m == 1 || (3 || ( 5 || ( 7 || ( 8 || ( 10 || ( 12 )))))))
{if (d <=31)
{legit=1;}}
else if (m == 4 || ( 6 || ( 9 || ( 11 ) ) ) )
{if (d <= 30)
{legit = 1;}}
else
{
if (leap == 1)
{if (d <= 29)
{legit = 1;}}
if (leap == 0)
{{if (d <= 28)
legit = 1;}}
}
}
if (legit==1)
printf("It is a legitimate date!\n");
else
printf("It's not a legitimate date!");
}
I am getting the correct output if the month has 31 days but for the rest of the months, the output is legitimate if the day is less than 32. Your help is appreciated!
i rewrite you program as simple and easy, i think this may help
//Legitimate date
#include <stdio.h>
void main()
{
int d,m,y;
int daysinmonth[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int legit = 0;
printf("Enter the date\n");
scanf("%i.%i.%i",&d,&m,&y);
// leap year checking, if ok add 29 days to february
if(y % 400 == 0 || (y % 100 != 0 && y % 4 == 0))
daysinmonth[1]=29;
// days in month checking
if (m<13)
{
if( d <= daysinmonth[m-1] )
legit=1;
}
if (legit==1)
printf("It is a legitimate date!\n");
else
printf("It's not a legitimate date!");
}
You can't chain conditionals like this:
if (m == 1 || (3 || ( 5 || ( 7 || ( 8 || ( 10 || ( 12 )))))))
Instead, you'll have to test each scenario specially:
if (m == 1 || m == 3 || m == 5 || ...)
Your version simply ORs the results of the first test (m == 1) with the value of 3, which in C is a non-zero and therefore always a boolean true.
This test is certainly wrong:
if (m == 1 || (3 || ( 5 || ( 7 || ( 8 || ( 10 || ( 12 )))))))
This must be
if ((m == 1) || (m == 3) || (m == 5) || ... )
Performing a logical or with a non-zero expression will always evaluate to true. Therefore, your entire test will always be true.
You can check date legitimacy simpler:
#define _XOPEN_SOURCE 600
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
time_t get_date(char *line){
#define WRONG() do{printf("Wrong date!\n"); return -1;}while(0)
time_t date;
struct tm time_, time_now, *gmt;
time_.tm_sec = 0;
time_.tm_hour = 0;
time_.tm_min = 0;
if(strchr(line, '.') && sscanf(line, "%d.%d.%d", &time_.tm_mday, &time_.tm_mon, &time_.tm_year) == 3){
time_.tm_mon--; time_.tm_year += (time_.tm_year < 100) ? 100 : -1900;
}else
WRONG();
memcpy(&time_now, &time_, sizeof(struct tm));
date = mktime(&time_now);
gmt = localtime(&date);
if(time_.tm_mday != gmt->tm_mday) WRONG();
if(time_.tm_mon != gmt->tm_mon) WRONG();
if(time_.tm_year != gmt->tm_year) WRONG();
date = mktime(&time_);
return date;
#undef WRONG
}
int main(int argc, char** argv){
struct tm *tmp;
if(argc != 2) return 1;
time_t GD = get_date(argv[1]);
if(GD == -1) return -1;
printf("Int date = %d\n", GD);
printf("your date: %s\n", ctime(&GD));
return 0;
}
//reading date and checking if valid or not
//firstly we will check the yeear then the month and then the date
//
//
//
//
#include<stdio.h>
int main()
{
int d,m,y;
printf("ENTER THE DATE IN DD/MM/YYYY FORMAT:");
scanf("%d%d%d",&d,&m,&y);
//check year
if(y>0 && y<9999)
{
// check month
if(m>=1 && m<=12)
{
if((d>=1 && d<=31) && (m==1 || m==3 || m==5 || m==7 || m==8 || m==10 || m==12))
printf("the date is valid in a month with 31 days:");
else if ((d>=1 && d<=30) && (m==4 || m==6 || m==9 || m==11 ))
printf("the date is valid in a feb with 30 days:");
else if ((d>=1 && d<=29) && (m==2) && ((y%400==0) || (y%4==0) && (y%100!=0)))
printf("the date is valid in feb of a leap year:");
else if ((d>=1 && d<=28) && (m==2) && (y%4==0) && (y%100==0))
printf("the date is valid in feb of a leap year:");
else if ((d>=1 && d<=28) && (m==2) && (y%4!=0) )
printf("the date is valid in feb of a non leap year:");
else
printf("the date is invalid:");
}
else
{
printf("the month is not valid:");
}
}
else
{
printf("the date is not valid:");
}
return 0;
}