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.
Related
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;
}
I am new to programming in general, recently decided to get serious about try to learn C. I am trying to build a light account program using nested loops and arrays.
I'm trying to build the program in CodeBlocks. My program is a little rough,
1) my first issue is that after my program asks how many weeks of work has been done, it then has grabs a value for the next loop, ignoring the value of weeks for at least the first loop.
2) Entering any integer other than "1" causes tax to pull a random value from memory, and even worse, it can overwrite the value for "weeks" despite there not being another scanf function for "weeks", often leading to the for...loop depending on the variable weeks to loop well into the millions.
3) I haven't programmed pathways 5 & 6 for void menu() yet due to the rest of the program not functioning properly
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int pay = 10;
const int overtime;
float taxrate;
int hours; //user input for hours worked
int gross; //calculated integer for gross pay
int tax; //calculated integer for taxes
int net; //calculated integer for net pay
int gross_total = 0; //non printed value for summing gross
int i; //condition to exit loop
void tax_rate();
void menu();
void cust_paid_yn();
void hours_worked();
int menu_input;
int menu_break;
char c;
int unpaid;
int weeks;
int j;
int week_numb_array[];
int gross_array[];
int tax_array[];
int gross_total_array[];
void printfinal();
int main(void)
{
menu();
printf("How many weeks have been worked?\n");
scanf("%d\n", &weeks);
for (int j = 0; j <= weeks; j++)
{
while (menu_input = 1 || 2 || 3 || 4)
{
hours_worked();
while ( hours != 1)
{
//uses hours to calculate gross, taxes, and net
gross = (hours * pay);
//use loop and gross to determine tax
tax_rate();
//uses hours to calculate taxes, net, and gross_total
tax = (gross * taxrate);
net = (gross - tax);
gross_total += (net);
gross_array[j] = gross;
tax_array[j] = tax;
gross_total_array[j] = gross_total;
break;
}
printf("\nexited out of menu_input loop\n");
break;
}
printf("\nexited out of tax loop\n");
printf("\n \n %d\n \n", weeks);
printf("\n \n %d\n \n", j);
}
printf("\nexited out of for...loop\n");
j = 0;
printfinal();
return 0;
}
void printfinal()
{
for (j = 0; j <= weeks; j++)
{
//Prints the title headers: gross pay, taxes and net pay
printf("Week Numb\t gross pay \t taxes \t net pay\n");
//Prints the calculations for gross, taxes, and net
printf("week 1\t\t %ld \t\t %ld \t\t %ld \t\n", gross_array[j],
tax_array[j], gross_total_array[j]);
}
return 0;
}
void tax_rate()
{
//use loop and gross to determine tax
if (gross <= 300)
{
taxrate = .15;
}
else if (gross <= 450)
{
taxrate = .20;
}
else if (gross >= 451)
{
taxrate = .25;
}
return 0;
}
void menu()
{
printf("Please make a selection from the following options\n 1) Set Pay
Rate to 8.75\n 2) Set Pay Rate to 9.33\n 3) Set Pay Rate to 10.00\n 4) Set Pay Rate to 11.20\n 5) Print Out List\n 6) Quit\n");
scanf("%d", &menu_input);
switch (menu_input)
{
case 1:
printf("Pay Rate set to 8.75\n");
menu_break = 0;
pay = 8.75;
break;
case 2:
printf("Pay Rate set to 9.33\n");
menu_break = 0;
pay = 9.33;
break;
case 3:
printf("Pay Rate set to 10.00\n");
menu_break = 0;
pay = 10.00;
break;
case 4:
printf("Pay Rate set to 11.20\n");
menu_break = 0;
pay = 11.20;
break;
case 5:
menu_break = 1;
printf("List Printed\n");
break;
case 6:
printf("QUIT\n");
menu_break = 2;
break;
default:
printf("Unknown\n");
menu_break = 3;
break;
}
return 0;
}
void cust_paid_yn()
{
for (i=0; i<1; 1)
{
//get input for whether cust. was paid
printf("Was customer paid this week? (y/n)\n");
scanf("%c", &c);
//loop to check for y/n response
switch (c)
{
case 'y':
printf("\n");
i=1;
hours = (hours + unpaid);
unpaid = 0;
break;
case 'n':
printf("hours logged\n");
i=1;
unpaid = (unpaid + hours);
hours = 0;
break;
default:
printf("\n");
i=0;
break;
}
break;
}
return 0;
}
void hours_worked()
{
//asks how many hours were worked
printf("How many hours were worked?\n \nIf no work was done enter 0\n");
//gets user input for hours worked
scanf("%ld", &hours);
return 0;
}
I just want to create a program that:
1) gets user input for how many time the program will loop (see weeks var)
2) print out user data using an array
Any help and suggestions are greatly appreciated, I'm at my wits end on why my program pulls random values from memory.
I'm making a 12-month calendar in C. A program that displays twelve-month calendar for a particular year. The program prompts the user for the year to be printed, and figures out (a) whether the year is a leap-year and (b) what day of the week the chosen year starts on.
Instructions:
• main() prompts the user for input, calls a function of your own design to determine the starting day of the input year. It then invokes the function printCalendar() to actually print the twelve month calendar.
• printCalendar() takes two arguments, the year number and the starting day. It then loops through the year and calls the function printMonth() twelve times, once for each month.
• printMonth() takes three arguments, the year number, the month number and the starting day of that particular month, and it returns the number of the day on which the next month starts. Print month has to first call a function printMonthName() and then print out the days of the month in calendar format.
• printMonthName() takes the year number and the month number as arguments, prints out the line identifying the month, and returns the number of days in that month, taking into account leap year.
I followed those instructions and got this far:
#include <stdio.h>
#include <stdlib.h>
int daysInMonth;
int getDayCode(int year);
void printCalendar(int year, int dayCode);
int getYear(void);
int getYear(void){
int year;
printf("Please enter a year: ");
scanf("%i", &year);
printf("\n");
return year;
}
int getDayCode(int year){
int dayCode;
int x1, x2, x3;
x1 = (year - 1.)/ 4.0;
x2 = (year - 1.)/ 100.;
x3 = (year - 1.)/ 400.;
dayCode = (year + x1 - x2 + x3) %7;
return dayCode;
}
main(){
int year, dayCode;
year = getYear();
dayCode = getDayCode(year);
printCalendar(year, dayCode);
}
void printCalendar(int year, int dayCode){
int month;
printf(" %d Monthly Calendar\n", year);
printf(" \n");
printf(" \n");
for (month = 1; month <= 12; month++){
printMonth(year, month, dayCode);
}
}
int printMonthName(int year, int month){
switch (month){
case 1:
printf("\n\nJanuary %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 2:
printf("\n\nFebruary %i", year);
if (year%4 == 0 && year%100 != 0 || year%400 == 0){
//printf("This is a leap year.\n");
daysInMonth = 29;
return daysInMonth;
}
else{
//printf("This is not a leap year.\n");
daysInMonth = 28;
return daysInMonth;
}
break;
case 3:
printf("\n\nMarch %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 4:
printf("\n\nApril %i", year);
daysInMonth = 30;
return daysInMonth;
break;
case 5:
printf("\n\nMay %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 6:
printf("\n\nJune %i", year);
daysInMonth = 30;
return daysInMonth;
break;
case 7:
printf("\n\nJuly %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 8:
printf("\n\nAugust %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 9:
printf("\n\nSeptember %i", year);
daysInMonth = 30;
return daysInMonth;
break;
case 10:
printf("\n\nOctober %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 11:
printf("\n\nNovember %i", year);
daysInMonth = 30;
return daysInMonth;
break;
case 12:
printf("\n\nDecember %i", year);
daysInMonth = 31;
return daysInMonth;
break;
default:
printf("Invalid input! Please try again!\n");
break;
}
}
int printMonth(int year, int month, int dayCode){
int day;
printMonthName(year, month);
printf("\n\nSun Mon Tue Wed Thu Fri Sat\n" );
/* advance printer to correct position for first date */
for (day = 1; day <= 1 + dayCode * 5; day++)
printf(" ");
/* print the dates for one month */
for (day = 1; day <= daysInMonth; day++){
printf("%2d", day);
if ((day + dayCode) % 7 > 0) /* before Sat? */
/* move to next day in same week */
printf(" ");
else /* skip to next line to start with Sun */
printf("\n ");
}
/* set day_code for next month to begin */
dayCode = (dayCode + daysInMonth % 7);
return dayCode;
}
I put 2013 as input year, and my code starts January 1st on Tuesday, which is correct. But it is also starting on Tuesday for all 12 months, here is the problem:
Calendar Output 2013
Please help. I've been trying to get this to work for a long time now.
It looks as if you return dayCode in your printMonth function. However, you never do anything with that value in your printCalendar function. This is easily fixed by changing your for loop in printCalendar.
for (month = 1; month <= 12; month++){
dayCode = printMonth(year, month, dayCode);
}
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;
}
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