2

I have to write a program the takes in two integers by the user, a and b, where a corresponds to the month of the year ( 1 = jan, 2 = feb etc.). The program has to print the month that comes after "a" and the following "b" months. This is what I have so far, but for every two integers I enter, I always get the same output: "January, February". Any help is appreciated.

#include<stdio.h>

        enum month {jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec}; /*This
allows yoou to name a finite set and to declare identifiers*/
        typedef enum month      month;

month next_month(month M)  /*this is a function definition*/
{
        switch (M) /* like an if-else statement, if this month is true goto the M=month you chose*/
        {
        case  jan:
                M=feb;break;
        case  feb:
                M=mar;break;
        case  mar:
                M=apr;break;
        case apr:
                M=may;break;
        case may:
                M=jun;break;
        case jun:
                M=jul;break;
        case jul:
                M=aug;break;
        case aug:
                M=sep;break;
        case sep:
                M=oct;break;
        case oct:
                M=nov;break;
        case nov:
                M=dec;break;
        case dec:
                M=jan;break;
        }
        return M;
}
void print_month (month M)  /*this is a function definition*/
{
        switch (M)  /* like an if-else statement, if this month is true goto the M=month you chose*/
        {
        case jan:
                printf("January");break;
        case feb:
                printf("February");break;
        case mar:
                printf("March");break;
        case apr:
                printf("April");break;
        case may:
                printf("May");break;
        case jun:
                printf("June");break;
        case jul:
                printf("July");break;
        case aug:
                printf("August");break;
        case sep:
                printf("September");break;
        case oct:
                printf("October");break;
        case nov:
                printf("November");break;
        case dec:
                printf("December");break;
        }
}
int main(void)
{
        month M, N, sat;
        printf("Please enter two integers:\n");
        scanf("%d%d", &M, &N);
        for (M = jan; M <= N; ((int)M++))
        {
                printf(" ");
                print_month(M);  /*function call to print month*/
                printf(" ");
                print_month(next_month(M));  /*function call to print previous month*/
                putchar('\n');
                return;
        }
}
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Kush
  • 21
  • 2
  • 3
  • 1
    If this is a homework problem, you should tag it as such. – Jollymorphic Mar 25 '11 at 23:31
  • 1
    do you have a debugger? Using a debugger and going through the code line by line will help immensely in your case... You'll be able to see which code doesn't behave as you expected. – hopia Mar 25 '11 at 23:39

6 Answers6

6

You have this in main

    scanf("%d%d", &M, &N);
    for (M = jan; M <= N; ((int)M++))
    {
         /* ... */
    }

So ... in the scanf line you change M (and N) to the values supplied by the user
and right after that you set M to jan effectively losing what he user chose.

You need to review the way you're doing it.

pmg
  • 106,608
  • 13
  • 126
  • 198
6

My suggestion for improving your program is to replace your switch statements with an array of month names. It would be a lot easier to program and to read.

It is usually a great improvement whenever you can replace code with data structures. This is something to remember and use whenever you do programming in the future.

So following my advice to use a month array would look a little bit like this:

#include <stdio.h>

const char* months[12] = {
 "January", "February", "March", "April", "May", "June",
 "July", "August", "September", "October", "November", "December"
};

int main(void)
{
    int m;
    printf("Enter month: ");
    scanf("%d", &m);
    if( 1 <= m && m <= 12 ) {
        printf("%s\n", months[m-1]);
    }
    return 0;
}
Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
5

return means return from the current function, so in the end of the first iteration of your for loop, you return from main function, and the program exits.

MByD
  • 135,866
  • 28
  • 264
  • 277
2

Try this code:

int main(void)
{
        int a, b, m;
        printf("Please enter two integers between 1-12:\n");
        scanf("%d%d", &a, &b);
        for (m=a+1; b; b--, m++)
        {
                printf(" ");
                print_month(m);  /*function call to print month*/
                putchar('\n');
        }
}

Take care, Beco

PS. Edited:

Also, change the enum line to:

    enum month {jan=1,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec};

And take care of the possible overflow a+b>12

2nd. Edition: Another explanation might be useful: you cannot use a return inside a loop like this and expect the loop will run, because at the time the computer runs the return it exits the program for good.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
DrBeco
  • 11,237
  • 9
  • 59
  • 76
  • I don't understand why someone would put a donwvote into a code that surely solves the problem. That is so lame. We try to help here. There are better answers, vote for them. 186 rep is not that big to not feel a downvote as very harsh. – DrBeco Mar 28 '11 at 20:17
  • BTW, the suggestion made by @Zan Lynx for the use of `const char* months[12] = { "January", ...` is far better than mine, but it address another problem, not the one in question. So go for it in your code. I even use this form in some programs of mine, but I forgot to include in my answer. Actually, the question was about why it was not working. Not to change the way the author was thinking. Now it is late. Maybe I should completely delete this answer if another ACA vote it down again. – DrBeco Mar 28 '11 at 20:25
0
include <stdio.h>

const char* months[12] = {
 "January", "February", "March", "April", "May", "June",
 "July", "August", "September", "October", "November", "December"
};

int main(void)
{
    int m;
    printf("Enter month: ");
    scanf("%d", &m);
    if( 1 <= m && m <= 12 ) {
        printf("%s\n", months[m-1]);
    }


    return 0;
}

Worked for me. thank you.

0

Check out C/C++ documentation of "%" and of macros - "#define". For this problem, Switches are unnecessary, inefficient and make code long.

Increment and modulus can be used to increment month. Enumerated value to sting can be done with a macro that replaces value code with string containing same code.

Enum to string using macros:
MSDN link - Stringizing Operator (#)

There are many ways to use this to convert enums to strings (Google it), including:

// Use correct number of parameters here (can use multiple macros)
#define ENUM_MACRO(name, offset, v1, v2, v3, v3)\
    enum name { v1 = offset, v2, v3, v4};\
    const char name##Strings[] = { #v1, #v2, #v3 };\
    const char* name##ToString(value) { return name##Strings[value - offset]; }

// This way you do not have two different
// lists of months to maintain in your code
// (the preprocessor creates them)
ENUM_MACRO(Month, 1, January, February, March);

//
// usage:
//
Month month = Month::Janurary;
const char* st = MonthToString(month);

//
// Incrementing month taking offset (1) and max (12) into account
//
month = (month + 1) % 12 + Month::Janurary;

Using these methods you can greatly reduce the size of your code, making it easier to read and maintain. Also - you improve performance by getting rid of all the branches.

Disclaimer - I haven't compiled this code, written from memory.

Danny Varod
  • 17,324
  • 5
  • 69
  • 111
  • Voting down for encouraging someone to learn and improve, instead of giving him answers to homework is lame! – Danny Varod Mar 25 '11 at 23:40
  • Switches are inefficient? Do you have any supporting information for this incredible claim? – dreamlax Mar 25 '11 at 23:44
  • I didn't vote you down but I don't see how your answer gives any help here. I have no idea how to improve his program with "%" and macros and I've been writing C for 15 years. :-) – Zan Lynx Mar 25 '11 at 23:45
  • Ifs for incremental month instead of (m+1) % 12 and ifs instead of enumerated to string using macro! Even with branch prediction you can't beat simple 1 line commands. – Danny Varod Mar 25 '11 at 23:59
  • 1
    Oh! Modulus operator: % and using the stringize feature of preprocessor macros to make use of a month name as both enum and string. – Zan Lynx Mar 26 '11 at 21:12
  • Could you explain a little bit more this solution? Maybe a little example would clarify it. Thanks. – DrBeco Mar 28 '11 at 20:34
  • Sure, I wrote the answer on my phone, so it was a bit hard to enter code. See the latest edit. – Danny Varod Mar 28 '11 at 20:41
  • +1 It works a charm. But there are some problems when compiling C. `#define ENUM_MACRO(name, offset, v1, v2, v3, v4, v5, v6)\ enum name { v1 = offset, v2, v3, v4, v5, v6};\ const char *name##Strings[] = { #v1, #v2, #v3, #v4, #v5, #v6};\ const char *name##ToString(value) { return name##Strings[value - offset]; } ENUM_MACRO(Month, 1, January, February, March, April, May, June); i. main(v.){ /* usage: */ int i;enum Month me=January; for(i=0; i<24; i++){ printf("%s, ", MonthToString(me)); me = ((++me)%13)?:January; }} /* trunked to june for lack of space in the comment */` – DrBeco Mar 29 '11 at 17:38
  • 1
    @Danny Sorry to keep you waiting. I didn't get notified. I used `enum Month month=January;` instead of `Month month = Month::Janurary;`. Also, the equation is `month = ((++month)%13)?:January;` instead of `month = (month + 1) % 12 + Month::Janurary;`. It is really nice. I just used this example here to explain another [list question](http://stackoverflow.com/questions/5530248/creating-a-string-list-and-an-enum-list-form-a-c-macro/)! ;) – DrBeco Apr 03 '11 at 16:57