w3resource

C Exercises: Calendar for any year

C Programming Challenges: Exercise-35 with Solution

Write a C program to generate a text calendar for any given year.

Sample Data:
C Programming: Colorful numbers.

C Code:

//#Source: shorturl.at/adgO5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int width = 80, year; 
int cols, lead, gap;

const char *wdays[] = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" };
struct months {
	const char *name;
	int days, start_wday, at;
} months[12] = {
	{ "January",	31, 0, 0 },
	{ "February",	28, 0, 0 },
	{ "March",	31, 0, 0 },
	{ "April",	30, 0, 0 },
	{ "May",	31, 0, 0 },
	{ "June",	30, 0, 0 },
	{ "July",	31, 0, 0 },
	{ "August",	31, 0, 0 },
	{ "September",	30, 0, 0 },
	{ "October",	31, 0, 0 },
	{ "November",	30, 0, 0 },
	{ "December",	31, 0, 0 }
};

void space(int n) { while (n-- > 0) putchar(' '); }

void init_months()
{
	int i;

	if ((!(year % 4) && (year % 100)) || !(year % 400))
		months[1].days = 29;

	year--;
	months[0].start_wday
		= (year * 365 + year/4 - year/100 + year/400 + 1) % 7;

	for (i = 1; i < 12; i++)
		months[i].start_wday =
			(months[i-1].start_wday + months[i-1].days) % 7;

	cols = (width + 2) / 22;
	while (12 % cols) cols--;
	gap = cols - 1 ? (width - 20 * cols) / (cols - 1) : 0;
	if (gap > 4) gap = 4;
	lead = (width - (20 + gap) * cols + gap + 1) / 2;
        year++;
}

void print_row(int row)
{
	int c, i, from = row * cols, to = from + cols;
	space(lead);
	for (c = from; c < to; c++) {
		i = strlen(months[c].name);
		space((20 - i)/2);
		printf("%s", months[c].name);
		space(20 - i - (20 - i)/2 + ((c == to - 1) ? 0 : gap));
	}
	putchar('\n');

	space(lead);
	for (c = from; c < to; c++) {
		for (i = 0; i < 7; i++)
			printf("%s%s", wdays[i], i == 6 ? "" : " ");
		if (c < to - 1) space(gap);
		else putchar('\n');
	}

	while (1) {
		for (c = from; c < to; c++)
			if (months[c].at < months[c].days) break;
		if (c == to) break;

		space(lead);
		for (c = from; c < to; c++) {
			for (i = 0; i < months[c].start_wday; i++) space(3);
			while(i++ < 7 && months[c].at < months[c].days) {
				printf("%2d", ++months[c].at);
				if (i < 7 || c < to - 1) putchar(' ');
			}
			while (i++ <= 7 && c < to - 1) space(3);
			if (c < to - 1) space(gap - 1);
			months[c].start_wday = 0;
		}
		putchar('\n');
	}
	putchar('\n');
}

void print_year()
{
	int row;
	char buf[32];
	sprintf(buf, "%d", year);
	space((width - strlen(buf)) / 2);
	printf("%s\n\n", buf);
	for (row = 0; row * cols < 12; row++)
		print_row(row);
}

int main(int c, char **v)
{ 
	int i, year_set = 0;
	printf("Input a valid year: ");
    scanf("%d", &year);
	for (i = 1; i < c; i++) {
		if (!strcmp(v[i], "-w")) {
			if (++i == c || (width = atoi(v[i])) < 20)
				goto bail;
		} else if (!year_set) {
			if (!sscanf(v[i], "%d", &year) || year <= 0)
				year = 1969;
			year_set = 1;
		} else
			goto bail;
	}

	init_months();
	print_year();
	return 0;

bail:	fprintf(stderr, "bad args\nUsage: %s year [-w width (>= 20)]\n", v[0]);
	exit(1);
}

Sample Output:

Input a valid year:                                       2022

            January                 February                 March        
      Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa
                         1           1  2  3  4  5           1  2  3  4  5
       2  3  4  5  6  7  8     6  7  8  9 10 11 12     6  7  8  9 10 11 12
       9 10 11 12 13 14 15    13 14 15 16 17 18 19    13 14 15 16 17 18 19
      16 17 18 19 20 21 22    20 21 22 23 24 25 26    20 21 22 23 24 25 26
      23 24 25 26 27 28 29    27 28                   27 28 29 30 31 
      30 31                                           

             April                    May                     June        
      Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa
                      1  2     1  2  3  4  5  6  7              1  2  3  4
       3  4  5  6  7  8  9     8  9 10 11 12 13 14     5  6  7  8  9 10 11
      10 11 12 13 14 15 16    15 16 17 18 19 20 21    12 13 14 15 16 17 18
      17 18 19 20 21 22 23    22 23 24 25 26 27 28    19 20 21 22 23 24 25
      24 25 26 27 28 29 30    29 30 31                26 27 28 29 30 

              July                   August                September      
      Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa
                      1  2        1  2  3  4  5  6                 1  2  3
       3  4  5  6  7  8  9     7  8  9 10 11 12 13     4  5  6  7  8  9 10
      10 11 12 13 14 15 16    14 15 16 17 18 19 20    11 12 13 14 15 16 17
      17 18 19 20 21 22 23    21 22 23 24 25 26 27    18 19 20 21 22 23 24
      24 25 26 27 28 29 30    28 29 30 31             25 26 27 28 29 30 
      31                                              

            October                 November                December      
      Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa
                         1           1  2  3  4  5                 1  2  3
       2  3  4  5  6  7  8     6  7  8  9 10 11 12     4  5  6  7  8  9 10
       9 10 11 12 13 14 15    13 14 15 16 17 18 19    11 12 13 14 15 16 17
      16 17 18 19 20 21 22    20 21 22 23 24 25 26    18 19 20 21 22 23 24
      23 24 25 26 27 28 29    27 28 29 30             25 26 27 28 29 30 31
      30 31 

Flowchart:

C Programming Flowchart: Colorful numbers.
C Programming Flowchart: Colorful numbers.
C Programming Flowchart: Colorful numbers.

C Programming Code Editor:

Contribute your code and comments through Disqus.

Previous C Programming Exercise: Colorful numbers.
Next C Programming Exercise: C Basic Declarations and Expressions Home

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Share this Tutorial / Exercise on : Facebook and Twitter

C Programming: Tips of the Day

What's an object file in C?

An object file is the real output from the compilation phase. It's mostly machine code, but has info that allows a linker to see what symbols are in it as well as symbols it requires in order to work. (For reference, "symbols" are basically names of global objects, functions, etc.)

A linker takes all these object files and combines them to form one executable (assuming that it can, i.e.: that there aren't any duplicate or undefined symbols). A lot of compilers will do this for you (read: they run the linker on their own) if you don't tell them to "just compile" using command-line options. (-c is a common "just compile; don't link" option.)

Ref : https://bit.ly/3CbzF8M