Days between dates will not compile - c

I have been trying to get this to work. I need to input 2 dates (MM DD) and then have the program tell me the amount of days between the 2 dates. But for some reason when i try to use month 2 (February) I dont think its registering that I indicated it having only 28 days. Also when i enter the same date i cant get it to say "0". Please help thank you
#include <stdio.h>
#include <stdlib.h>
//constructs dates for calculation
struct date{
int month;
int day;
};//end date
int main()
{
struct date first, second; //creates 2 dates to calculate
int finalDays = 0;
int total = 0;
int i = 0;
int valid=0;
printf("Enter first date \n");
scanf("%d %d", &first.month, &first.day); //user input: first date
if (first.month == 1||3||5||7||8||10){
if(first.day > 31){
printf("Invalid Day\n");
valid += 1;
}
}
else if (first.month == 4||6||9||11 ){
if (first.day > 30){
printf("Invalid Day\n");
valid += 1;
}
}
else if (first.month == 2){
if(first.day > 28){
printf("Invalid Day");
valid += 1;
}
}
printf("Enter second date\n");
scanf("%d %d", &second.month, &second.day); // user input: second date
if (second.month == 1||3||5||7||8||10){
if(second.day > 31){
printf("Invalid Day\n");
valid += 1;
}
}
else if (second.month == 4||6||9||11 ){
if (second.day > 30){
printf("Invalid Day\n");
valid += 1;
}
}
else if (second.month ==2){
if(second.day > 28){
printf("Invalid Day");
valid += 1;
}
}
if (first.month == second.month && first.day == second.day){
printf("Days between dates: 0");
valid += 1;
}
//Prints statement if month is invalid
if(first.month > 12 || second.month > 12 || first.month<1 || second.month<1){
printf("Invalid Date: Invalid month");
}
//Prints statement if second date precedes first
if(second.month<first.month){
printf("Invalid. Second date cannot precede first date.");
}
if (second.month==first.month && second.day<first.day){
printf("Invalid. Second date cannot precede first date.");
}
if(first.month==second.month){
finalDays = (second.day - first.day);
printf("Days between dates: %d", finalDays);
valid+=1;
}
if(first.month == 1||3||5||7||8||10||12) // Days remaining in first month
total = 31 - first.day;
else if(first.month == 4||6||9||11)
total = 30 - first.day;
else if(first.month == 2)
total = 28 - first.day;
for(i = first.month + 1; i < second.month; i++)
{
if(i == 3||5||7||8||10||12)
total += 31;
else if(i == 4||6||9||11)
total += 30;
}
total += second.day;
if(valid == 0){
printf("First date: %d %d \n", first.month, first.day);
printf("Second date: %d %d \n", second.month, second.day);
printf("Days between dates: %d", total);
}
return 0;
} //end main

if (first.month == 1||3||5||7||8||10){
This won't do what you want it to do. It will be evaluated as (first.month == 1)||3||5||7||8||10, which will evaluate to true for all non-zero months.
This would be better written as a case statement;
switch (first.month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
/* Handle 31 day months */
...
break;
case 4:
case 6:
case 9:
case 11:
/* Handle 30 day months */
...
break;
case 2:
/* Handle February */
...
break;
default:
/* Handle invalid month */
break;
}

Related

How do I use switch case properly?

Can anyone tell me am I using switch cases correct? because when I input other number, it's output is always January.
#include <stdio.h>
int main()
{
int month, date, year;
printf("Enter Month Number: ");
scanf("%d", &month);
if (month > 12){
printf("Invalid Month! please choose a number below 12");
}
else{
printf("\nEnter Date Number: ");
scanf("%d", &date);
if (month = 1, 3, 5, 7, 8, 10, 12){
if (date > 31){
printf("\nInvalid Date! please choose a number below 31");
}
else{
printf("\nEnter Year: ");
scanf("%d", &year);
if (year > 9999){
printf("\nPlease make sure your year is correct!");
}
else if (year < 1000){
printf("\nPlease make sure your year is correct!");
}
else{
switch(month){
case 1:
printf("\nJanuary %d, %d", date, year);
break;
case 3:
printf("\nMarch %d, %d", date, year);
break;
case 5:
printf("\nMay %d, %d", date, year);
break;
case 7:
printf("\nJuly %d, %d", date, year);
break;
case 8:
printf("\nAug %d, %d", date, year);
break;
case 10:
printf("\nOctober %d, %d", date, year);
break;
case 12:
printf("\nDecember %d, %d", date, year);
break;
}
}
}
}
else if (month = 4, 6, 9, 11){
if (date > 30){
printf("\nInvalid Date! please choose a number below 30");
}
else{
printf("\nEnter Year: ");
scanf("%d", &year);
if (year > 9999){
printf("\nPlease make sure your year is correct!");
}
else if (year < 1000){
printf("\nPlease make sure your year is correct!");
}
else{
switch(month){
case 4:
printf("\nApril %d, %d", date, year);
break;
case 6:
printf("\nJne %d, %d", date, year);
break;
case 9:
printf("\nSeptember %d, %d", date, year);
break;
case 11:
printf("\nNovember %d, %d", date, year);
break;
}
}
}
}
else if (month = 2){
if (date > 29){
printf("\nInvalid Date! please choose a number below 29");
}
else{
printf("\nEnter Year: ");
scanf("%d", &year);
if (year > 9999){
printf("\nPlease make sure your year is correct!");
}
else if (year < 1000){
printf("\nPlease make sure your year is correct!");
}
else{
printf("\nFebruary %d, %d", date, year);
}
}
}
}
return 0;
}
A few issues ...
= is the assignment operator. You want the equality operator ==
if (month = 4, 6, 9, 11) is just incorrect syntax. As mentioned in the top comments, this would be done with a switch/case block or if ((month == 4) || (month == 6) || (month == 9) || (month == 11)).
The code is needlessly verbose. Having a struct that describes the month (days and month string) and an array of it greatly simplifies the code.
Prompting the user for all three values before doing checking can also simplify the code.
Here is a simplified version. It is annotated:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
struct month {
int days; // (max) number of days in month
const char *str; // month string
};
struct month months[12] = {
{ 31, "January" },
{ 29, "February" },
{ 31, "March" },
{ 30, "April" },
{ 31, "May" },
{ 30, "June" },
{ 31, "July" },
{ 31, "August" },
{ 30, "September" },
{ 31, "October" },
{ 30, "November" },
{ 31, "December" },
};
// asknum -- prompt user for number within a given range
int
asknum(const char *prompt,int lo,int hi)
{
char buf[100];
char *cp;
long val;
// prompt the user
printf("Enter %s (%d to %d): ",prompt,lo,hi);
fflush(stdout);
// get user's response -- exit on EOF
if (fgets(buf,sizeof(buf),stdin) == NULL)
exit(7);
// check for empty string
if (buf[0] == '\n') {
printf("No value specified\n");
exit(8);
}
// decode the value
errno = 0;
val = strtol(buf,&cp,10);
// check for error detected by strtol
if (errno != 0) {
printf("Invalid number\n");
exit(9);
}
// check for syntax error
if (*cp != '\n') {
printf("Invalid syntax\n");
exit(10);
}
// check range of number
if ((val < lo) || (val > hi)) {
printf("Number out of range -- must be between %d and %d\n",
lo,hi);
exit(11);
}
return val;
}
// isleap -- decide if it's a leap year
int
isleap(int year)
{
int leap = 0;
do {
if ((year % 4) != 0)
break;
if ((year % 400) == 0) {
leap = 1;
break;
}
if ((year % 100) == 0)
break;
leap = 1;
} while (0);
return leap;
}
int
main(void)
{
int month, date, year;
int days;
int leap = 0;
month = asknum("Month Number",1,12);
// locate the month descriptor
const struct month *mon = &months[month - 1];
date = asknum("Date Number",1,mon->days);
year = asknum("Year",1000,9999);
// get days in the month
days = mon->days;
// special case for february
if (month == 2) {
leap = isleap(year);
if (! leap)
days -= 1;
}
// check date against number of days in the month
if (date > days) {
printf("%s only has %d days\n",mon->str,days);
exit(2);
}
// print the date
printf("%s %d, %d\n",mon->str,date,year);
return 0;
}

Including Math.h results in errors in cmath

In my includes I used #include , but when I attempt to compile and run the program it gives me a long list of syntax errors. Visual studio tells me the errors are in the file cmath, which I did not include nor use in the program
Program works perfectly in C++ but not in c
This is all my includes:
#include <iostream>
#include <stdio.h>
#include <math.h>
This is the only place I use any type of math from math.h:
double compoundinterest(double principle, double interest, double years) {
float a = 1 + (interest);
float b = pow(a, years);
return principle * b;
Error output log:
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\include\cstdlib(20,51): error C2061: syntax error: identifier 'noexcept'
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\include\cstdlib(20,51): error C2059: syntax error: ';'
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\include\cstdlib(20,60): error C2449: found '{' at file scope (missing function header?)
(edit: removed most of the errors because they were very similar and took up too much space)
Entire program:
#include <iostream>
#include <stdio.h>
#include <math.h>
int leapyears(int year);
int numberofdays(int month, int day, int year);
int monthlength(int month, int year);
double compoundinterest(double principle, double interest, double years);
double simpleinterest(double principle, double interest, double years);
int main(void) {
int option = 5;
int month, day, year;
printf("option 0: exit program\n");
printf("option 1: Calculate and display the day of the week of a given date\n");
printf("option 2: Calculate and display the principal on a savings account after a given number of years for compounded interest.\n");
printf("option 3: Calculate and display the principal on a savings account after a given number of years for simple interest\n");
while (option != 0) {
int days, week;
double p, i, y;
printf("enter an option: ");
scanf("%d", &option);
switch (option) {
case 0:
printf("goodbye\n");
break;
case 1:
printf("enter the date in the format month day year in numerical form: \n");
scanf(" %d %d %d", &month, &day, &year);
days = numberofdays(month, day, year);
week = days % 7;
switch (week) {
case 1:
printf("tuesday\n");
break;
case 2:
printf("wednesday\n");
break;
case 3:
printf("thursday\n");
break;
case 4:
printf("friday\n");
break;
case 5:
printf("saturday\n");
break;
case 6:
printf("sunday\n");
break;
default:
printf("monday\n");
break;
}
break;
case 2:
printf("Enter the initial principle, interest rate(as a decimal), and number of years for compound interest: \n");
scanf(" %lf%lf%lf", &p, &i, &y);
printf("Your principle would be valued at %lf\n", compoundinterest(p, i, y));
break;
case 3:
printf("Enter the initial principle, interest rate(as a decimal), and number of years for simple interest: \n");
scanf(" %lf%lf%lf", &p, &i, &y);
printf("Your principle would be valued at %lf\n", simpleinterest(p, i, y));
break;
default:
printf("invalid entry\n");
break;
}
}
return 0;
}
int leapyears(int year) {
if ((year % 4) == 0) {
if ((year % 100) != 0) return 1;
if ((year % 100) == 0) {
if ((year % 400) == 0) {
return 1;
}
else return 0;
}
}
else return 0;
}
int monthlength(int month, int year) {
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) return 31;
if (month == 4 || month == 6 || month == 9 || month == 11) return 30;
if (leapyears(year) == 1 && month == 2) {
return 29;
}
if (leapyears(year) == 0 && month == 2) {
return 28;
}
}
int numberofdays(int month, int day, int year) {
day -= 1;
while (year != 0001) {
if (leapyears(year) == 1) {
day += 366;
}
else{
day += 365;
}
year -= 1;
}
while (month != 1) {
month -= 1;
day += monthlength(month, year);
}
return day;
}
double compoundinterest(double principle, double interest, double years) {
float a = 1 + (interest);
float b = pow(a, years);
return principle * b;
}
double simpleinterest(double principle, double interest, double years) {
return principle * (1 + (years * interest));
}
You are including C++ headers in your C file. If you remove the #include <iostream> line, it should fix these errors.

Weird output Calendar in C

I have programmed a very simple calendar in C. It takes the year as input and will then calculate the dates and weekdays for that year.
This assuming that the date 0001-01-01 is a monday.
I've gotten it to work pretty good except in one place. When it's about to print out the line with all the 31st dates.
Basically what's going wrong is, when it's going to check if there is anything to print at april 31st (which there isn't), it bugs out the weekday variable. Which makes the following 31st dates wrong.
Is there anyone who can see if I made something wrong or might wanna help me out? :)
EDIT Forgot to mention that it's a task ment to be solved without any formulas for calculating the daycode and so on. The only reference allowed to be used is that the date 0001-01-01 is a monday.
Heres my code. (Yes it's a bit messy atm, but I'm still learning.)
int isLeapYear(int year){
if(((year%4==0) && (year%100!=0)) || (year%400==0)){
return 1;
}
else
return 0;
}
int getYear(){
int year = 0;
while(year==0 || year < 0){
printf("Enter year: ");
scanf("%d", &year);
if(year > 0){
break;
}
printf("Invalid input. Try again.\n\n");
}
return year;
}
void printWeekday(int w){
switch(w){
case 0:
printf("Sun");
break;
case 1:
printf("Mon");
break;
case 2:
printf("Tue");
break;
case 3:
printf("Wed");
break;
case 4:
printf("Thu");
break;
case 5:
printf("Fri");
break;
case 6:
printf("Sat");
break;
}
}
void printMonth(int m){
switch(m){
case 1:
printf("Jan");
break;
case 2:
printf(" Feb");
break;
case 3:
printf(" Mar");
break;
case 4:
printf(" Apr");
break;
case 5:
printf(" May");
break;
case 6:
printf(" Jun");
break;
case 7:
printf(" Jul");
break;
case 8:
printf(" Aug");
break;
case 9:
printf(" Sep");
break;
case 10:
printf(" Oct");
break;
case 11:
printf(" Nov");
break;
case 12:
printf(" Dec\n");
break;
}
}
void calendar(int year){
int y = 1;
int m = 1;
int d = 1;
int loop = 1;
int day = 1;
int days_in_month[14] = {0,31,28,31,30,31,30,31,31,30,31,30,31,0};
if(isLeapYear(year)){
days_in_month[1] = 29;
}
for(m=1; m<=12; m++){
printMonth(m);
}
while(loop){
int weekday = 1;
for(y=1; y<=year; y++){
for(m=1; m<=12; m++){
for(d=1; d<=31; d++){
if(weekday%7 == 0){
// printf("h");
weekday = 0;
}
if(y==year){
if(day>days_in_month[m]){
printf(" ");
printf("%d", weekday);
break;
}else if(d == day){
//printf("%d", weekday);
if(m == 1){
printf("%02d ", d);
printWeekday(weekday);
}else if(m == 12){
printf(" %02d ", d);
printWeekday(weekday);
printf("\n");
}else{
printf(" %02d ", d);
printWeekday(weekday);
}
}
}
if(d<=days_in_month[m]){
weekday = weekday + 1;
}
}
}
}
day++;
if(day == 32){
break;
}
}
}
int main()
{
int end = 1;
while(end){
int year = getYear();
printf(" %d\n", year);
calendar(year);
printf("\nEnter 0 to quit: ");
scanf("%d", &end);
//system("cls");
}
return 0;
}
Here, inside of calendar() function add this code:
if(day>days_in_month[m] /*Add this code: */ && d>days_in_month[m]){
printf(" ");
printf("%d", weekday);
break;
}else if(d == day){...
Where is problem? Well, did you see the 31st day of march? Its a Saturday:
At the end of iteration of days (I mean for(d=1; d<=31; d++){ loop ) you iterate the weekday. So First April should be Sunday. Which is valid if you check results.
But, you calculate weekday by day of month. So when we print 31 first March, our day variable is equal to 31.
Now, the March is ended (we print 31st day of March), our weekday sets on Sunday. And we go to calculate days of April. But look at your code, inside of for(d=1; d<=31; d++) loop, you have if(day>days_in_month[m]) {break;}.
And when our program checks first day of April, and day is equal to 31, then its stop calculating days for April with break instruction. We go to calculate days of May. But our weekday still remains as Sunday. If you see the valid code, first may should be Tuesday. But when day variable equal to 31, first may starts as Sunday. And starting with 1st May all days calculated wrong.
PROBLEM WITH LEAPS YEARS:
Because you use this:
if(isLeapYear(year)){
days_in_month[2] = 29;
}
It adds 29th day for each year (So you add three 29th days to first three years, and you see the result in 1st january of 4th year :) ).
To solve it, delete those piece of code. And inside of loop for months, add variable that will represent number of days:
for(m=1; m<=12; m++){
int monthDays = days_in_month[m]; /*Add this variable*/
if (m==2 && isLeapYear(y))
monthDays++; // Add 29th day to feb. of leap year
for(d=1; d<=31; d++){...
And inside of function, replace all days_in_month[m] to monthDays
Instead of holding a weekday variable you can call a function which will calculate the day of the week given the date. For this you can use Tomohiko Sakamoto's Day of the week algorithm.
int dayofweek(int d, int m , int y){
static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
y -= m < 3;
return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}
// 0 - Sunday
// 1 - Monday and so on
If you wish to understand this algorithm you can see a detailed explanation here : https://www.quora.com/How-does-Tomohiko-Sakamotos-Algorithm-work
But since you are a beginner I wouldnt really recoment it :) Its a little confusing.
After implementing this you can then simplify your calendar function to be
void calendar(int year) {
int days_in_month[14] = { 0,31,28,31,30,31,30,31,31,30,31,30,31,0 };
if (isLeapYear(year)) {
days_in_month[2] = 29;
}
for (int m = 1; m<=12; m++) {
printMonth(m);
}
for (int d = 1; d<=31; d++) {
for (int m = 1; m<=12; m++) {
if (d <= days_in_month[m]) {
int weekday = dayofweek(d, m, year);
printf("%02d ", d);
printWeekday(weekday);
printf(" ");
}
else {
printf(" ");
}
}
printf("\n");
}
}
This is actually a much more efficient way of generating the weekday rather than looping through the whole year

Program that displays each digit on an integer in english doesn't work with an integer beginning with "0"

I have an assignment were I have to write a program that takes an integer keyed in from the terminal and extracts and displays each digit of the integer in English. I'm not able to use arrays or recursion, we're just starting with programming.
For example:
"123" returns "one two three"
My program is working well (for the most part), but the problem is that when you enter something like "0123" in the terminal the program returns "eight three"... WTH??
This is my code:
// Program that takes an integer and displays each digit in English
#include <stdio.h>
int main (void)
{
int num, digit;
int reversed = 0, backupZero = 0;
printf("Please enter an integer:\n");
scanf("%i", &num);
if (num == 0) // In case the input is just "0"
{
printf("zero");
}
while (num > 0) // Loop to reverse the integer
{
digit = num % 10;
reversed = (reversed * 10) + digit;
if ((reversed == 0) && (digit == 0)) // If the integer finishes in zero
{
++backupZero; // Use this to add extra zeroes later
}
num /= 10;
}
while (reversed > 0)
{
digit = reversed % 10;
reversed /= 10;
switch (digit)
{
case 1:
printf("one ");
break;
case 2:
printf("two ");
break;
case 3:
printf("three ");
break;
case 4:
printf("four ");
break;
case 5:
printf("five ");
break;
case 6:
printf("six ");
break;
case 7:
printf("seven ");
break;
case 8:
printf("eight ");
break;
case 9:
printf("nine ");
break;
default:
printf("zero ");
break;
}
}
for (int counter = 0; counter < backupZero; ++counter) // Prints the extra zeroes at the end
{
printf("zero ");
--backupZero;
}
printf("\n");
return 0;
}
Probably is something on the mathematics, I admit I'm not good at it.
When you read in the number with
scanf("%i", &num);
You are letting scanf infer the base of the number. Numbers starting with 0 followed by other digits are interpreted as octal. So 0123 is not the same as 123. It is in fact, 83.
0100 = 64
020 = 16
03 = 3
---------
0123 = 83
To read the number as base 10, use
scanf("%d", &num);
If you want to handle numbers that start with '0', then I suggest that you read the user input as a string (array of characters) rather than as an integer.
In addition to that, instead of "doing a switch" on each character, you can use a simple array in order to map the correct word to each digit.
Here is one way for implementing it:
#include <stdio.h>
#define MAX_INPUT_LEN 100
const char* digits[] = {"zero","one","two" ,"three","four",
"five","six","seven","eight","nine"};
int main()
{
int i;
char format[10];
char str[MAX_INPUT_LEN+1];
sprintf(format,"%c%us",'%',MAX_INPUT_LEN); // now format = "%100s"
scanf(format,str); // will write into str at most 100 characters
for (i=0; str[i]!=0; i++)
{
if ('0' <= str[i] && str[i] <= '9')
printf("%s ",digits[str[i]-'0']);
else
printf("invalid character ");
}
return 0;
}
Oh, wow. It took me 3 or 4 hours to write following code. I'm into c only first week, so please be considerate.
Update: added working minus + some comments.
#include <stdio.h>
#include <math.h>
int main(void)
{
int num, count, user, out;
count = 0;
printf("Type in any int: ");
scanf("%d", &num);
// adding minus to the beginning if int is negative
if (num < 0)
{
num = -num;
printf("minus ");
}
user = num;
// creating a power to the future number
while (num != 0)
{
num = num / 10;
count++;
}
int i2;
i2 = count;
// main calculations: dividing by (10 to the power of counter) and subtracting from the initial number
for (int i = 0; i < i2; i++)
{
out = user / pow(10, count - 1);
user = user - out * pow(10, count - 1);
count--;
switch (out)
{
case 1:
printf("one ");
break;
case 2:
printf("two ");
break;
case 3:
printf("three ");
break;
case 4:
printf("four ");
break;
case 5:
printf("five ");
break;
case 6:
printf("six ");
break;
case 7:
printf("seven ");
break;
case 8:
printf("eight ");
break;
case 9:
printf("nine ");
break;
case 0:
printf("zero ");
break;
default:
break;
}
}
printf("\n");
return 0;
}
There are some mistakes:
if ((reversed == 0) && (digit == 0)) (incorrect)
if ((reversed == 0) || (digit == 0)) (correct)
And in the last loop you should remove
--backupZero;
And code will read numbers better

How do I use a for loop to retrieve from the user the indicated number of items indicated?

int a = 1;
printf("Enter the number of items from 1 and 10: \n");
while (a <= 10)
{
scanf("%d", &a);
if (a >= 1 && a <= 10)
{
printf("Thank You!\n");
break;
}
else
{
printf("Wrong input! Try Again.\n");
continue;
}
}
To be more detailed about what I'm asking lets say that the user enters 3 (for 3 items) how would I use the for loop to retrieve that information so I can further finish the code.
You should keep in mind following points:
Get the no.of choice before starting loop
Check the condition in loop with no. of choices.
Only one loop is enough for your task.
I think you need this:
int a = 1;
bool bFlag = true;
int price[10];
printf("Enter the number of items from 1 and 10: \n");
while(bFlag){
scanf("%d", &a);
if (a >= 1 && a <= 10)
{
printf("Thank You!\n");
break;
}
else
{
printf("Wrong input! Try Again.\n");
continue;
}
}
for (int i = 0; i< a; i++)
{
printf("Enter price for item %d = ", i);
scanf("%d",&price[i]);
}

Resources