Solved

creating a calendar in c

Posted on 2006-11-23
12
447 Views
Last Modified: 2010-04-15
I need to create a program in c to print a calendar for one year, given the year and day of the week that Jan 1 falls on. Input should come from keyboard and output to a file. User needs to be prompted to enter the year and a number for which day of week Jan 1 starts on i.e. 1 for Sunday, 2 for Monday etc. I need to create one with and without using functions. Can anybody help ? I'm quite desperate.
0
Comment
Question by:JeffreyMihocik
12 Comments
 
LVL 15

Expert Comment

by:bpmurray
ID: 18004464
Sounds like homework. Have a look at the source for the Unix/Linux cal command below. While it's reasonably straightforward to do this, there are lots of gotchas. Since this version calculates the Jan 1 day, you can strip that logic out.


/*      from Unix 32V /usr/src/cmd/cal.c      */
/*
 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *   Redistributions of source code and documentation must retain the
 *    above copyright notice, this list of conditions and the following
 *    disclaimer.
 *   Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *   All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed or owned by Caldera
 *      International, Inc.
 *   Neither the name of Caldera International, Inc. nor the names of
 *    other contributors may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
 * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4
#define      USED      __attribute__ ((used))
#elif defined __GNUC__
#define      USED      __attribute__ ((unused))
#else
#define      USED
#endif
static const char sccsid[] USED = "@(#)cal.sl      1.12 (gritter) 5/29/05";

#include      <unistd.h>
#include      <time.h>
#include      <stdio.h>
#include      <libgen.h>
#include      <stdlib.h>
#include      <locale.h>
#include      <langinfo.h>
#include      <string.h>
#include      <wchar.h>
#include      <limits.h>

static wchar_t      dayw[] = {
      ' ', 'S', ' ', ' ', 'M', ' ', 'T', 'u', ' ', ' ',
      'W', ' ', 'T', 'h', ' ', ' ', 'F', ' ', ' ', 'S', 0
};
static char      *smon[]= {
      "January", "February", "March", "April",
      "May", "June", "July", "August",
      "September", "October", "November", "December"
};
static char      *amon[] = {
      "Jan", "Feb", "Mar", "Apr",
      "May", "Jun", "Jul", "Aug",
      "Sep", "Oct", "Nov", "Dec"
};
static char      string[432];
static char      *progname;

static void      usage(void);
static void      bad(void);
static void      dolocale(void);
static int      number(const char *str);
static void      pstr(char *str, int n);
static void      cal(int m, int y, char *p, int w);
static int      jan1(int yr);
static void      wput(const wchar_t *);

int
main(int argc, char **argv)
{
      register int y = 1, i, j;
      int m = 1;

      progname = basename(argv[0]);
      dolocale();
      if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-'
                  && argv[1][2] == '\0')
            argv++, argc--;
      if (argc == 2)
            goto xlong;
      else if (argc == 1) {
            time_t t;
            struct tm *tp;

            time(&t);
            tp = localtime(&t);
            m = tp->tm_mon + 1;
            y = tp->tm_year + 1900;
      } else if (argc == 3) {
            /*
              *      print out just month
              */
            m = number(argv[optind]);
            if(m<1 || m>12)
                  bad();
            y = number(argv[optind + 1]);
            if(y<1 || y>9999)
                  bad();
      } else
            usage();
      printf("   %s %u\n", smon[m-1], y);
      wput(dayw);
      putchar('\n');
      cal(m, y, string, 24);
      for(i=0; i<6*24; i+=24)
            pstr(string+i, 24);
      exit(0);

/*
 *      print out complete year
 */

xlong:
      y = number(argv[optind]);
      if(y<1 || y>9999)
            bad();
      printf("\n\n\n");
      printf("                        %u\n", y);
      printf("\n");
      for(i=0; i<12; i+=3) {
            for(j=0; j<6*72; j++)
                  string[j] = '\0';
            printf("       %.3s", amon[i]);
            printf("                  %.3s", amon[i+1]);
            printf("                   %.3s\n", amon[i+2]);
            wput(dayw);
            printf("   ");
            wput(dayw);
            printf("   ");
            wput(dayw);
            putchar('\n');
            cal(i+1, y, string, 72);
            cal(i+2, y, string+23, 72);
            cal(i+3, y, string+46, 72);
            for(j=0; j<6*72; j+=72)
                  pstr(string+j, 72);
      }
      printf("\n\n\n");
      return 0;
}

static int
number(const char *str)
{
      register int n, c;
      register const char *s;

      n = 0;
      s = str;
      while((c = *s++) != '\0') {
            if(c<'0' || c>'9')
                  return(0);
            n = n*10 + c-'0';
      }
      return(n);
}

static void
pstr(char *str, int n)
{
      register int i;
      register char *s;

      s = str;
      i = n;
      while(i--)
            if(*s++ == '\0')
                  s[-1] = ' ';
      i = n+1;
      while(i--)
            if(*--s != ' ')
                  break;
      s[1] = '\0';
      printf("%s\n", str);
}

char      mon[] = {
      0,
      31, 29, 31, 30,
      31, 30, 31, 31,
      30, 31, 30, 31,
};

static void
cal(int m, int y, char *p, int w)
{
      register int d, i;
      register char *s;

      s = p;
      d = jan1(y);
      mon[2] = 29;
      mon[9] = 30;

      switch((jan1(y+1)+7-d)%7) {

      /*
       *      non-leap year
       */
      case 1:
            mon[2] = 28;
            break;

      /*
       *      1752
       */
      default:
            mon[9] = 19;
            break;

      /*
       *      leap year
       */
      case 2:
            ;
      }
      for(i=1; i<m; i++)
            d += mon[i];
      d %= 7;
      s += 3*d;
      for(i=1; i<=mon[m]; i++) {
            if(i==3 && mon[m]==19) {
                  i += 11;
                  mon[m] += 11;
            }
            if(i > 9)
                  *s = i/10+'0';
            s++;
            *s++ = i%10+'0';
            s++;
            if(++d == 7) {
                  d = 0;
                  s = p+w;
                  p = s;
            }
      }
}

/*
 *      return day of the week
 *      of jan 1 of given year
 */

static int
jan1(int yr)
{
      register int y, d;

/*
 *      normal gregorian calendar
 *      one extra day per four years
 */

      y = yr;
      d = 4+y+(y+3)/4;

/*
 *      julian calendar
 *      regular gregorian
 *      less three days per 400
 */

      if(y > 1800) {
            d -= (y-1701)/100;
            d += (y-1601)/400;
      }

/*
 *      great calendar changeover instant
 */

      if(y > 1752)
            d += 3;

      return(d%7);
}

static void
usage(void)
{
      fprintf(stderr, "usage: %s [ [month] year ]\n", progname);
      exit(2);
}

static void
bad(void)
{
      fprintf(stderr, "Bad argument\n");
      exit(1);
}

#define      COPY_DAY(d)            cp = nl_langinfo(DAY_##d); \
                        cp += mbtowc(wq++, cp, MB_CUR_MAX); \
                        cp += mbtowc(wq++, cp, MB_CUR_MAX); \
                        wq++

#define      COPY_MONTH(m)            smon[m - 1] = strdup(nl_langinfo(MON_##m))

#define      COPY_ABMON(m)            amon[m - 1] = strdup(nl_langinfo(ABMON_##m))

static void
dolocale(void)
{
      char *cp;
      wchar_t *wq;

#ifndef      __dietlibc__
      setlocale(LC_CTYPE, "");
      cp = setlocale(LC_TIME, "");
      if (cp && strcmp(cp, "C") && strcmp(cp, "POSIX") && strcmp(cp, "en") &&
                  strncmp(cp, "en_", 3)) {
#else      /* __dietlibc__ */
      if (1) {
#endif      /* __dietlibc__ */
            wq = dayw;
            COPY_DAY(1);
            COPY_DAY(2);
            COPY_DAY(3);
            COPY_DAY(4);
            COPY_DAY(5);
            COPY_DAY(6);
            COPY_DAY(7);
            COPY_MONTH(1);
            COPY_MONTH(2);
            COPY_MONTH(3);
            COPY_MONTH(4);
            COPY_MONTH(5);
            COPY_MONTH(6);
            COPY_MONTH(7);
            COPY_MONTH(8);
            COPY_MONTH(9);
            COPY_MONTH(10);
            COPY_MONTH(11);
            COPY_MONTH(12);
            COPY_ABMON(1);
            COPY_ABMON(2);
            COPY_ABMON(3);
            COPY_ABMON(4);
            COPY_ABMON(5);
            COPY_ABMON(6);
            COPY_ABMON(7);
            COPY_ABMON(8);
            COPY_ABMON(9);
            COPY_ABMON(10);
            COPY_ABMON(11);
            COPY_ABMON(12);
      }
}

static void
wput(const wchar_t *s)
{
      char      mb[MB_LEN_MAX];
      int      i, n;

      s--;
      while (*++s) {
            n = wctomb(mb, *s);
            for (i = 0; i < n; i++)
                  putchar(mb[i] & 0377);
      }
}
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 18004489
Hi JeffreyMihocik,

If this is homework I would strongly suggest you try to do it yourself and ask us when you get stuck. If you submit something professionally written like the code above you will almost certainly get into a whole heap of trouble, however much you play with it.

Do what you can and come back here with some code to post and what goes wrong or doesnt work and we can help you.

Paul
0
 
LVL 15

Expert Comment

by:bpmurray
ID: 18004699
And that's the reason I posted it :-)
0
 

Author Comment

by:JeffreyMihocik
ID: 18005747
Yeah, it's homework, but I need to get something done by this weekend. I've written some stuff without functions but I don't know how to start it outputting in certain positions. If you give me your e mail address I'll send you what i've got already. I'm a computer idiot but any help would be appreciated so I can survive this program and the class.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18006328
>> I've written some stuff without functions but I don't know how to start it outputting in certain positions.
Can you paste what you have in here ?
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 24

Expert Comment

by:fridom
ID: 18006436
the base standard libraries do not have any support for outputting at certain places. Howerver there do exit libraries for that.

So I'd argue what you are looking for is some usage of printf or the like
so maybe something like

printf("%d %d %d", day1, day2, day3) or the like.

Regards
Friedrich
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 18006985
>>If you give me your e mail address I'll send you what i've got already.
FYI: This is against the rules of EE. ( http://www.experts-exchange.com/help.jsp#hi99 )
Please post code here.

Paul <Page Editor>
0
 
LVL 15

Accepted Solution

by:
bpmurray earned 125 total points
ID: 18007615
It sounds to me that you don't have a clear picture of the solution in your head. Without this, you're not going to complete this assignment. As an example (remember this is my thought process - you may think in a completely different way):

What do I want to do?
       Display a calendar.
              Each month should have headers: the name centered on top, list of day abbreviations below.
              Each day can be 2 digits (2 screen positions) + a space; each week = 7x2 + (7-1)x1 = 20 characters wide
              On an 80-character screen I can accomodate 3 weeks: the calendar can be three months wide, four months deep.
              This means display should be done 3 months at a time across the page, but we'll keep it simple for now and only do one wide
       Calculate the day it starts:
              LeapYear = (Year%4 == 0 && Year%100>0) ? 1 : 0;
              The months have known lengths: J=31, F=28+LeapYear, M=31, A=30, M=31, J=30, J=31, A=31, S=30, O=31, N=30, D=31
              This means that the first of each month = (FirstDayOfPreviousMonth + MonthLength) % 7
       What artefacts do I need?
              A table of month names = char*[12]
              A table of month lengths = int[12]
              A table of first days = int[12]
      How do I display?
             For each month
                  Display headers (make this a function)
                  Skip first few days, displaying spaces if it doesn't start on a Sunday
                  Print the days

and so on.
0
 
LVL 84

Expert Comment

by:ozo
ID: 18010440
LeapYear = (Year%4 == 0 && Year%100>0 || Year%400==0)
0
 
LVL 15

Expert Comment

by:bpmurray
ID: 18010853
Oops forgot about that, and only did it a few years ago too!
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Picking random number 8 169
Adjust Mfcapp 29 155
why "." vs "->" 23 116
C++ finding a sting in a char* string from a text file 3 92
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now