Matthew Schell
Matthew Schell

Reputation: 679

Why is my programming printing out 1 statement twice and not following execution order?

I'm trying to create a bank management program. I ask the user whether they want to login or create an account. If the user enters anything other than 1 (create account) or 2 (login), I want to tell them that they entered something wrong, and then I ask the same question again until they get it right. However, after they enter something wrong, this happens:

  1. Program sleeps for 3 seconds
  2. Error message is printed along with the question for logging in or creating an account
  3. The above 2 steps are repeated again except it allows the user to input their option again on the second time

What I want to happen is this (in order):

  1. Print error message
  2. Print the 3 dots after the error message
  3. Ask question again and wait for user input

Here's the code:

#include "functions.h"

#define clear() printf("\033[H\033[J") //function to clear terminal screen

int main(void) {
    clear();
    void (*funcptr)(void);
    int option;
    char *endptr;

    printf("=========================================Login or Create Account=========================================\n\n");
    while(1) {
        printf("Welcome to the Bank management program! Would you like to 1. Create Account or 2. Login?\n>>> ");
        option = fgetc(stdin);

        switch (option) {
            case('1'):
                funcptr = create_account;
                break;

            case('2'):
                funcptr = login;
                break;

            default:
                printf("\n\033[0;31m[ERROR] Invalid option. Please enter the number of the option that you want to choose");
                print_dots(3);
                printf("\n\033[0m");
                continue;
            }
        break;
        }
    funcptr();
    return 0;
}

Here's the output:

=========================================Login or Create Account=========================================

Welcome to the Bank management program! Would you like to 1. Create Account or 2. Login?
>>> 9

[ERROR] Invalid option. Please enter the number of the option that you want to choose...
Welcome to the Bank management program! Would you like to 1. Create Account or 2. Login?
>>> 
[ERROR] Invalid option. Please enter the number of the option that you want to choose...
Welcome to the Bank management program! Would you like to 1. Create Account or 2. Login?
>>> 

I've had a similar issue with this before and it was solved with fflush(stdout). The problem is that I don't know where to put this statement, if it is the solution to the problem. Can someone help me please?

Upvotes: 1

Views: 120

Answers (1)

user9706
user9706

Reputation:

The terminal is in cooked mode (at least that is the Linux term) which allows the user certain amount of command-line editing. When user is done they press enter ('\n'). What is tripping you up is that the stream (buffer) that fgetc reads from contains all the user input including the '\n'. This means if user inputs "9\n" the first call to fgetc will return 9, and the next call will return '\n'.

The suggestion was to add a case for '\n':

case '\n':
  continue;

This does fix original problem but I am going to goto next; instead to avoid the Welcome string being shown twice:

#include <stdio.h>

#define clear() printf("\033[H\033[J") //function to clear terminal screen

void create_account() {
    printf("create account\n");
}

void login() {
    printf("login\n");
}


int main(void) {
    clear();
    void (*funcptr)(void);
    int option;
    char *endptr;

    printf("=========================================Login or Create Account=========================================\n\n");
    while(1) {
        printf("Welcome to the Bank management program! Would you like to 1. Create Account or 2. Login?\n>>> ");
next:
        option = fgetc(stdin);

        switch (option) {
            case '\n':
                goto next;
            case('1'):
                funcptr = create_account;
                break;

            case('2'):
                funcptr = login;
                break;

            default:
                printf("\n\033[0;31m[ERROR] Invalid option. Please enter the number of the option that you want to choose");
                printf("...");
                printf("\n\033[0m");
                continue;
        }
        funcptr();
    }
    return 0;
}

and here is the matching output:

=========================================Login or Create Account=========================================

Welcome to the Bank management program! Would you like to 1. Create Account or 2. Login?
>>> 1
create account
Welcome to the Bank management program! Would you like to 1. Create Account or 2. Login?
>>> 2
login
Welcome to the Bank management program! Would you like to 1. Create Account or 2. Login?
>>> ^C

Upvotes: 3

Related Questions