0

I apologize for the long code, but this is part of a big project for school and I tried to consolidate as much as I could while still being able to compile it. My issue is that when I access the getFisherman() function and select register a fisher man from the menu. The first thing that it's supposed to ask for is the user's SSN number then store the user input in an array. However, when you select the register a fisherman option, it skips over the SSN user input and goes right to the first name option instead. I can't figure out why. Any help would be appreciated. I'm also new to this so any other advice would be appreciated. Thank you very much!

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <mem.h>


struct Fisherman
{
    //declare all attributes: ssn, first, last, phone, email
    //optional attributes: disqualified of type boolean
    int ssn[10];
    char fName[100];
    char lName[100];
    int phoneNo[10];
    char email[100];

}typedef Fisherman;

Fisherman F1;

int mainMenu();
int FishermanMenu();
void getFisherman();

int main()
{
    //declare all working variables: mOption, FManOption, COption...etc...
    int MOption = 0;
    int FManOption = 0;
    int FOption = 0;
    int COption = 0;
    int userChoice = 0;



    //declarations for all arrays of struct
    Fisherman F1[100];

    //declare a pointer to an array of struct using malloc() for fisherman, fish, catch
    Fisherman* pFisherman = (Fisherman*)malloc(100 * sizeof(Fisherman));

    //process:
    printf("Please select 1 to start the program or 0 to quit: ");
    scanf("%d", &userChoice);
    while(userChoice != 1 && userChoice != 0)
    {
        printf("Invalid selection! Please type a 1 or a 0: ");
        scanf("%d", &userChoice);
    }//end (userChoice != 1 && userChoice != 0)
    if(userChoice != 1)
    {
        printf("Thank you for wasting my time! Have a great day!\n");
        return 0;
    }
        while(MOption != 5)
        {

            MOption = mainMenu();
            switch(MOption)
            {
            case 1: FManOption = FishermanMenu();
                    if(FManOption != 3)
                    {
                        switch(FManOption)
                        {
                            case 1: getFisherman();//get a fisherman
                                    //count fisherman
                                    break;
                            case 2:
                                    //prompt for a ssn, validate, search
                                    //if found display everything about this fisherman
                                    break;
                            case 3: getch();

                                    //reset FManOption
                                    break;
                            default: printf("\nInvalid selection! Please select from one of the menu options\n");
                        }//end switch(FManOption)
                    }//end while(FManOption != 3)
                    break;
            }
        }
}

int mainMenu(MOption)
{
    printf("\n-------Welcome to the Fishing Tournament Main Menu!-------\n");
    printf("1 - Fisherman menu\n");
    printf("2 - Fish menu\n");
    printf("3 - Tournament(Catch) menu\n");
    printf("4 - Close Tournament (determine winner)\n");
    printf("5 - Quit Program\n\n");
    printf("Please select a menu option: ");
    scanf("%d", &MOption);
    if(MOption > 5 || MOption < 1)
        do /* check scanf() return value for input errors */
        {
            printf("\nInvalid selection! Please select from one of the menu options\n");
            printf("1 - Fisherman menu\n");
            printf("2 - Fish menu\n");
            printf("3 - Tournament(Catch) menu\n");
            printf("4 - Close Tournament (determine winner)\n");
            printf("5 - Quit Program\n\n");
            printf("Please select a menu option: ");
            scanf("%d", &MOption);
        }
        while(MOption > 5 || MOption < 1);

    return MOption; /* finally return the final correct option */
}//end main menu
//-----------------------------------------------------------

int FishermanMenu(FManOption)
{
    printf("\n-------Fisherman Menu-------\n");
    printf("1 - Register fisherman\n");
    printf("2 - Search fisherman\n");
    printf("3 - Go back to main menu\n");
    printf("Please select a menu option: ");
    scanf("%d", &FManOption);
    if(FManOption > 3 || FManOption < 1)
        do /* check scanf() return value for input errors */
        {
            printf("\nInvalid selection! Please select from one of the menu options\n");/* handle input error */
            printf("1 - Register fisherman\n");
            printf("2 - Search fisherman\n");
            printf("3 - Go back to main menu\n");
            printf("Please select a menu option: ");
            scanf("%d", &FManOption);
        }
        while(FManOption > 3 || FManOption < 1);
    return FManOption; /* finally return the final correct option */
}//end Fisherman Menu

void getFisherman()
{
    int userSelection = 0;
    int ssn[100];
    char fName[100];
    char lName[100];
    int phoneNo[100];
    char email[100];

    printf("Please enter the fisherman's SSN:\n");
    fgets(ssn, 40, stdin);
    printf("Please enter the fisherman's first name: ");
    fgets(fName, 40, stdin);
    printf("Please enter the fisherman's last name: ");
    fgets(lName, 40, stdin);
    printf("Please enter the fisherman's phone number: ");
    fgets(phoneNo, 40, stdin);
    printf("Please enter the fisherman's email address: ");
    fgets(email, 40, stdin);
    printf("Fisherman has been registered!\n");

    printf("Press 1 to register another fisherman or 0 to return back to main menu: ");
    scanf("%d", &userSelection);
    if(userSelection == 1)
        getFisherman();
    while(userSelection > 1 || userSelection < 0)
    {
        printf("Invalid selection! Please select 1 or 0: ");
        scanf("%d", &userSelection);
        break;
    }


    //use fgets and all associated functions and pointer to get data about a
    //fisherman

}//end getFisherman
tlbiro
  • 63
  • 8
  • Mega 'newline left in buffer' dupe:( – Martin James Aug 16 '21 at 03:32
  • 1
    In [my answer to your previous question](https://stackoverflow.com/a/68780314/12149471), in which I recommended that you use `fgets` instead of `scanf`, I explicitly warned you about mixing these two functions, because I was afraid that exactly this would happen. Although it is possible to use both functions in the same program, I generally don't recommend it, as it can easily cause errors, unless you know exactly what you are doing. In general, I recommend that you only use `fgets` instead of `scanf`, as that function always reads one line at a time, provided the buffer is large enough. – Andreas Wenzel Aug 16 '21 at 04:23
  • Although I have already provided this link to you in my answer to your other question, it seems appropriate to also provide it in this context: [A beginners' guide away from scanf()](http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html) – Andreas Wenzel Aug 16 '21 at 04:27
  • I would also like to point out again that it is not necessary to duplicate all of these `printf` lines when printing the main menu. See my answer to your other question for a way that you only have to write these lines once in your code. Code duplication is generally a bad thing that should be avoided, because when changing the code, you must always remember to change the code in all places in which the code is duplicated. Also, it is more work to change the code, if it is duplicated in several places. – Andreas Wenzel Aug 16 '21 at 04:55
  • Instead of writing `fgets(email, 40, stdin);`, you can simply write `fgets(email, sizeof email, stdin);`. This has the advantage that if you change the size of `email` when you declare it, you don't have to change the size in the `fgets` function call, too. – Andreas Wenzel Aug 16 '21 at 04:58
  • Note that when using `fgets` to read a string, you generally want to remove the newline character, which `fgets` always writes into the buffer (assuming the buffer was large enough to read the entire line). See [this question](https://stackoverflow.com/q/2693776/12149471) for the best ways to remove the newline character. Note that in my answer to your previous question, I did not do this, because it was not necessary, because I was ignoring all whitespace (which includes the newline character). – Andreas Wenzel Aug 16 '21 at 05:03
  • In contrast to C++, in C, it is not necessary to cast the result of `malloc`. See this question for further information: [Do I cast the result of malloc?](https://stackoverflow.com/q/605845/12149471) – Andreas Wenzel Aug 16 '21 at 05:06
  • @AndreasWenzel For malloc we had to implement this as a requirement for our project that is why it is in there. I don't fully understand malloc either but I will read your post about casting the result of malloc. So how can I change all the `scanf()` options to `fgets`? How I understand `fgets` is that it stores the user input in an array but can I also store this input into a single variable. Thank you again for your response. – tlbiro Aug 16 '21 at 13:48
  • @AndreasWenzel could you also please point me in the right direction in my last question where I can minimize the `printf` statements? I believe that you told me, but I am not comprehending where I can remove the repetitive code at. Like how should it be written instead? Thank you, – tlbiro Aug 16 '21 at 17:10
  • @tlbiro: I suggest that you search [my answer to your previous question](https://stackoverflow.com/a/68780314/12149471) for the words "It is also worth noting that your functions `mainMenu` and `FishermanMenu` contain unnecessary code duplicaton." In that place of my answer, I show how to remove the code duplication, by using an infinite loop. The line `for (;;)` is the traditional way to write an infinite loop, but you can also write `while (1)`. Both are equivalent. – Andreas Wenzel Aug 16 '21 at 17:36
  • Perfect. I do remember seeing that and sorry again for the confusion. I'll refer back to my previous question. Thank you! – tlbiro Aug 16 '21 at 17:45
  • 1
    @tlbiro: `"So how can I change all the scanf() options to fgets?"` -- In my proposed solutions, I used the function `fgets` to read the line into a buffer as a string, followed by using the function [`strtol`](https://en.cppreference.com/w/c/string/byte/strtol) to convert that string into a number. See my function `get_int_from_user`, which is identical in all three of my proposed solutions. – Andreas Wenzel Aug 16 '21 at 17:57
  • 1
    If you want to mix `scanf` and `fgets` (which I don't recommend), then that is possible too. However, since `scanf` only reads a line partially and does not remove the newline character from the stream, you must remove these leftovers of `scanf` before calling `fgets`, for example like this: `int c; do { c = getchar(); } while ( c != EOF && c != '\n' );` Note that I cannot write any newlines into comments, so you will have to add them yourself to my code. – Andreas Wenzel Aug 16 '21 at 18:03
  • Ok when I have access to my code later on I will try and switch everything to `fgets` and see how that goes. Is coding always this complicated for noobs? – tlbiro Aug 16 '21 at 18:07
  • @tlbiro: You are right that programming in C is not very friendly for beginners. Other languages are easier in that respect. For example, they provide functions such as `get_int_from_user` for you. In C, you must write these functions yourself, or use a third-party library. As far as I'm concerned, I have nothing against you using my function `get_int_from_user` in your code, but I'm afraid that your professor would not like that. – Andreas Wenzel Aug 16 '21 at 18:18
  • @AndreasWenzel Yeah that is my concern as well. I appreciate you helping me and offering me your code to use. Honestly, I may just need to turn in what I have and accept the grade I deserve and if I can't pass then I need to try harder next semester. Not the end of the world. – tlbiro Aug 16 '21 at 18:28
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236064/discussion-between-andreas-wenzel-and-tlbiro). – Andreas Wenzel Aug 16 '21 at 18:31

0 Answers0