0

I am trying to write a program to check validity of month entered by user. Here are my codes:


int monthcheck(int m) {
    int month = 0;
    while (m <= 0 || m > 12) {
        printf("Month must be between 1 and 12, re-enter month:");
        scanf("%d", &m);
    }
    if (m == 2) {
        month = 1; // February
    }
    if (m==1||m==3||m==5||m==7||m==8||m==10||m==12) month=2;
    return month;
}

    int main()
{
        int m;
        printf("Enter month");
        scanf("%d",&m);
        if (monthcheck(m)==0) printf("The month is valid");
        else if (monthcheck(m)==1) printf("The month is february");
}

And here is my output:

Enter month-2
Month must be between 1 and 12, re-enter month:13
Month must be between 1 and 12, re-enter month:2
Month must be between 1 and 12, re-enter month:2
The month is february

My question is: why does the program still ask me to enter another input (at line 4) although it is not meet the conditions of while loop? Help is appreciated. Many thanks!

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • First of, **never** use `scanf()` without checking it's return value. If your scan failed, you wouldn't even know it. – DevSolar Feb 15 '23 at 14:45
  • 7
    You're calling `monthcheck(m)` twice with the same input. So if it goes into the while loop the first time it's going to go into it the second time too. – Kevin Feb 15 '23 at 14:47
  • @BRemmelzwaal The result of `monthcheck(m)` isn't saved. After the user enters a valid month, `monthcheck(m)` (the *original, still invalid month value* of `m`) is called again in the next if check. – Kevin Feb 15 '23 at 14:51
  • 1
    As soon as you start to learn C++ programming, you must also learn how to step through your code in a debugger. Doing so would have answered your question very quickly. – Drew Dormann Feb 15 '23 at 14:54
  • 1
    Since `monthcheck` does not receive `m` by reference, it doesn't actually change, and therefore remains invalid during the `else if` where you call `monthcheck` a second time. – AndyG Feb 15 '23 at 14:55
  • 1
    There's a design problem here; it doesn't directly affect the result, but it makes the code very confusing. `main` is responsible for getting the value of `m`, and `monthcheck` is also responsible for getting a valid value of `m` and doing some classification. This mixes up responsibilities. Write one function to get `m` and validate it; write a different function to do the classification. `int get_month()` and `int checkmonth(int month)` or something like that. Note that I changed the name of the check function so that it's a verb phrase; functions do things, so should usually be verbs. – Pete Becker Feb 15 '23 at 15:00
  • 3
    Functions should do one thing each. It can be a little tricky to decide what "one thing" means, but surely a function named "monthcheck" should just *check* the month, not input a new month in the event that the check fails. – John Bollinger Feb 15 '23 at 15:00
  • Have you tried running your code line-by-line in a debugger while monitoring the control flow and the values of all variables, in order to determine in which line your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Wenzel Feb 15 '23 at 15:00
  • Thanks everyone for your advices. I understand the problem now. I'll also look up for debugging right away. – Johnny K18 HCM Feb 15 '23 at 15:04

1 Answers1

0

The second if statement is called

    else if (monthcheck(m)==1) printf("The month is february");

if the expression in the first if statement

    if (monthcheck(m)==0) printf("The month is valid");

evaluates to false.

The both if statements call the function with the unchanged variable m declared in main.

So when you entered 2 the first time within the function then the function returned the value 1 due to this if statement

if (m == 2) {
    month = 1; // February
}

And the body of the first if statement within main was skipped and the second if statement got the control that again called the function with the initial value of the variable m equal to -2 because the variable in main was not changed.

Now again the function returned the value 1 and the body of the second if statement got the control.

This output

Enter month-2
Month must be between 1 and 12, re-enter month:13
Month must be between 1 and 12, re-enter month:2

is generated by the first function call called in the expression of the first if statement.

And this output

Month must be between 1 and 12, re-enter month:2
The month is february

is generated by the second function call called in the expression of the second if statement when the function was called with the same value of the variable m equal to -2.

is generated At least you should write the if statements like

    if ( ( m = monthcheck(m) ) == 0 ) printf("The month is valid");
    else if ( m == 1 ) printf("The month is february");

Though the function does not make a great sense because the value 1 returned by the function is also valid. That is it is unclear what you are trying to achieve with using the function.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thank you for your reply. I am new to programming so I am experimenting a bit. My initial purpose was to validate a date (d/m/y) entered by user. The above codes is the function to validate the month. With other advices from replies above and your explaination, I understand the problem now and took another approach. I seperated to function into 2 smaller functions: one is to check for validity and returns the month, the other is to check for which month have 30 days, 31 days and 28/29 for february and return 0,1,2,3 respectively. All in all, the codes run smoothly. – Johnny K18 HCM Feb 15 '23 at 15:44
  • @JohnnyK18HCM I'm glad to hear that. If the problem is resolved then close your question selecting the best answer and your reputation will be increased.:) – Vlad from Moscow Feb 15 '23 at 16:00