Does an "if - else" statement always need the "else"?

5 months ago by printf("%s", name); to c/c_lang

Hello there! I am playing around at random for now before continuing reading the litterature that I am using to learn C.

What is a less "ugly" way to break out the while loop at the last if-else statement than leaving else empty? I guess I could have avoided this if I knew how to terminate the program at the switch - case (E) other that break -ing out of it as I am now, in other words, not having to "climb" out of switch , then while and then reaching "Goodbye!".

#include <stdio.h>  
#include <string.h>  

//Save "pins" in an array with an upper limit of ten pins. "Saved pins" resets if the upper limit is reached.  
int main(void) {  

    int pin = 0;  
    int check = 0;  

    //Saved pins  
    int pin_history[10]={0,0,0,0,0,0,0,0,0,0};  
    int pin_history_index = 0;  
    int pin_history_limit = 10;  

    int choice = 0;  

    printf("Enter your new pin: ");  
    scanf("%d", &pin);  
    getchar();  
    printf("Confirm your new pin: ");  
    while ((scanf("%d", &check))) {  
        if (check != pin) {  
            getchar();  
            printf("\nMismatch! Confirm your new pin: ");  
        }  
        else if (check == pin) {  
            pin_history[pin_history_index] = pin;  
            pin_history_index = pin_history_index + 1;  
            if (pin_history_index >= pin_history_limit) pin_history_index = 0;  
            printf("\nYour new pin has been saved successfully!\n");  
            break;  
        }  
    }  

    printf("What would you like to do next?\n\n(V)iew your saved pins\n(S)ave another pin\n(E)xit\n");  
    while ((choice = getchar()) != EOF) {  
        switch (choice) {  
            case ('V'):  
                printf("\nYour saved pins are:\n");  
                for (int i = 0; i < pin_history_limit; ++i) {  
                printf("%d\n", pin_history[i]);  
                }  
                printf("\nWhat would you like to do next?\n(V)iew your saved pins\n(S)ave another pin\n(E)xit\n");  
                break;  
            case ('S'): {  
                printf("\nEnter your new pin: ");  
                scanf("%d", &pin);  
                getchar();  
                printf("Confirm your new pin: ");  
                while ((scanf("%d", &check))) {  
                    if (check != pin) {  
                        getchar();  
                        printf("\nMismatch! Confirm your new pin: ");  
                    }  
                    else if (check == pin) {  
                        getchar();  
                        pin_history[pin_history_index] = pin;  
                        pin_history_index = pin_history_index + 1;  
                        if (pin_history_index >= pin_history_limit) pin_history_index = 0;  
                        printf("\nYour new pin has been saved successfully!\n");  
                        printf("What would you like to do next?\n\n(V)iew your saved pins\n(S)ave another pin\n(E)xit\n");  
                        break;  
                    }  
                }  
                break;  
            }  
            case ('E'): break;  
        }  
        if (choice == 'E') break;  
        else;  
    }  
    printf("\nGoodbye!\n");  
    return 0;  
}  
AlSweigart 9 points 5 months ago

The else isn't needed, as others have said. I'd find, install, and configure a linter tool, which can give you pointers on small stylistic issues like this.

path: 0 23629996, hotness: undefined, score: 9, children: 1
akunohana 2 points 5 months ago

Sweet! I'll check it out! 😊

path: 0 23629996 23630409, hotness: undefined, score: 2, children: 0
redlemace 6 points 5 months ago

an " if ... else ... " always needs an else to be an "if ... else" statement ;)

but you can just create an "if..... " statement So you can change

        }  
        if (choice == 'E') break;  
        else;  
    }  
    printf("\nGoodbye!\n");  
    return 0;  
}  

into

        }  
        if (choice == 'E') break;  
    }  
    printf("\nGoodbye!\n");  
    return 0;  
}  
path: 0 23629525, hotness: undefined, score: 6, children: 1
akunohana 4 points 5 months ago

Ah, gotcha! Thanks!

path: 0 23629525 23629683, hotness: undefined, score: 4, children: 0
sobchak 3 points 5 months ago

Yeah. Not necessarily applicable here, but in general, it's good practice to use guard clauses/early return when appropriate which don't have else (https://en.wikipedia.org/...). Deep nesting is usually best avoided and a "code-smell" indicating that you may want to do something different.

path: 0 23631536, hotness: undefined, score: 3, children: 0
CameronDev 2 points 5 months ago

The else is definitely not needed, you can delete it.

As for the best way to climb out of a nested loop, this is one of the occasions that a goto is reasonable. The jump would be relatively short and localised, which is exactly what GOTO should be used for:

What's with the getchars slapped everywhere? I think its an attempt to flush stdin, but I think you need to do it repeatedly until you hit a newline or EOF.

I think your next step is to refactor the code into some functions, you have two nearly identical code sections for adding a new pin, you can make that a function and simplify it.

path: 0 23629752, hotness: undefined, score: 2, children: 5
akunohana 2 points 5 months ago

"Slapped" 🤣 I think I forgot to remove the getchars after having used scanf, I had learned here. As you said, to clean up the input buffer.

I had JUST written down in my TODO list to make a function of it! 😁

Thank you so much! 😊

path: 0 23629752 23630482, hotness: undefined, score: 2, children: 0
akunohana 2 points 5 months ago

I've been at it for two days without researching and I can't figure out how to "hand over" the updates of the history array from within my "new pin" function to the main() function. I have to learn about scopes. Good fun!

path: 0 23629752 23645744, hotness: undefined, score: 2, children: 3
CameronDev 2 points 5 months ago

Pass the history array into your new function via a pointer.

I don't know what you mean by "without researching", but that is a very hardcore way to learn C. Respect!

path: 0 23629752 23645744 23646837, hotness: undefined, score: 2, children: 2
akunohana 2 points 5 months ago

Thanks for the pointers. 😝

Oh, I just meant that I'm experimenting, evaluating and thinking instead of "just" searching for a straight answer on the world wide web.

Edit: Also meaning, that when I post a question here, I have already writhen (spelling?) in pain for a few hours or a day without getting anywhere.

path: 0 23629752 23645744 23646837 23646930, hotness: undefined, score: 2, children: 1
CameronDev 2 points 5 months ago

That's fair enough, and a good way to learn. Still, in this day and age with Claude etc, I respect the effort you're putting in.

In the interests of proposing alternatives, you could also make the pin list a global variable. I'll let you work out why its a bad idea though :)

path: 0 23629752 23645744 23646837 23646930 23647242, hotness: undefined, score: 2, children: 0
c_lang
c_lang

@programming.dev

login for more options
1357
103
28

Welcome to the C community!

C is quirky, flawed, and an enormous success.
... When I read commentary about suggestions for where C should go, I often think back and give thanks that it wasn't developed under the advice of a worldwide crowd.
... The only way to learn a new programming language is by writing programs in it.

© Dennis Ritchie

🌐 https://en.cppreference.com/w/c

go to feed...