-2

I'm trying to get the user of a C program to Enter M for Male and F for Female and to loop through if it doesn't meet M or F . Below I have tried the following code but it loops twice giving the correct answer. For instance after entering M it loops and prints

FALSE gender .. please enter M for Male and M for Female

is there any way to solve it .

The goal is if the user enter M or F it will work without needing to enter it a second time.
if anything else it may ask a number of times

 #include "Gender.h"
 #include<stdio.h>


  char sex;
  void Gender(){

  printf("\nEnter Student Gender ('example M for Male  F for Female):\n");

  scanf(" %s",&sex);



      while (sex != "M" || sex != "M"){
       printf ("\n FALSE gender .. please enter M for Male and M for Female:\n");
        scanf(" %s",&sex);
        printf("\nStudent Sex :%c", sex,"\n");
        return;
      }


  }
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Angelo
  • 39
  • 1
  • 1
  • 7
  • 2
    The expression in the `while` statement is checking `"M"` twice. Also, to compare strings in C, use the `strcmp` function. – user3386109 Apr 23 '19 at 23:09
  • 1
    And use `&&` instead of `||`. – Ruud Helderman Apr 23 '19 at 23:10
  • `"%s"` consumes leading whitespace, so the space in `" %s"` is not needed -- HOWEVER, you do not check the return (ignoring a manual `EOF`) and you fail to remove any extraneous characters beyond the first character (e.g. after reading `sex`, `int c = getchar(); while (c != '\n' && c != EOF) c = getchar();`) This beyond your mismatch in types between `char sex` and `"%s"` expecting a pointer to char with sufficient storage to hold the string (including the *nul-terminating* character) – David C. Rankin Apr 23 '19 at 23:13
  • 1
    **M** for Male and **M** for Female (inside the loop)? I think the ladies are entitled to feel annoyed. The `return` inside the loop means that people get one retry, which isn't tested. You also throw away the result of the user's input — that's not very good. Surely you should return the selected gender? It might be worth adding a count on the retries and stopping people from going into a loop. Stop after 10 failed attempts, for example. – Jonathan Leffler Apr 23 '19 at 23:23
  • @JonathanLeffler I now realize my typo but still when i change the F for female it still does the same thing. – Angelo Apr 24 '19 at 01:53
  • 1
    Can I downvote the instructor who assigned this? – R.. GitHub STOP HELPING ICE Apr 24 '19 at 03:24

2 Answers2

5

sex is a single char variable, but you are treating it as a pointer to a string.

  1. Change your scanf call to have %c (single character) in the format string, rather than %s.
  2. Change your tests for the value of sex to use single quotes (i.e. if (sex == 'M')).

Note that though this code should not need string comparison if the variable sex is treated like the single char it is, if you were to compare strings in a future project, you would not use the operators == and != - instead, use the function strcmp in <string.h>

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
  • 1
    Should point out when the user does enter something that is not M or F then you should read up to the new line character and dispose of that data in the stream – Ed Heal Apr 24 '19 at 01:22
1

Several things, I've provided an implementation with comments...

Include ctype.h to use toupper(3) and allow both upper and lower case entry. You can either use character comparison, or string comparison, I gave you both, pick one.

#include "Gender.h"
#include <stdio.h>

//you should really define these in your Gender.h file...
#define MALE "M"
#define FEMALE "F"
//you should really define these in your Gender.h file...
static const char* GenderAllowed = MALE" for Male and "FEMALE" for Female";
static const char* GenderPrompt = "Enter Student Gender";

//compare as string[1] - keep either this
#include <string.h>
int sexValidc( char* sex ) {
    return ( (0==strncmp(sex,MALE,1)) || (0==strncmp(sex,FEMALE,1)) );
}

//compare only first character - or keep this
#include <ctype.h>
int sexValids( char* sex ) {
    char sexch = toupper(*sex); //fold first character to upper case
    return ( (*MALE==sexch) || (*FEMALE==sexch) );
}

char Gender() {
    char sex[69+1]; //since you wanted to use %s, need a buffer, your &char allows stack overflow & wild memory pointer-ing
    printf("\n%s (%s):\n",GenderPrompt,GenderAllowed); //DRY - Dont Repeat Yourself...
    int done = 0;
    while( !done ) {
        scanf(" %69s",sex); //avoid stackoverflow :-)
        if( !sexValidc( sex ) ) {
//printf("blech, entered: %s\n",sex); //debugging, remove when comfortable
            printf("\n FALSE gender .. %s %s:\n",GenderPrompt,GenderAllowed);
        }
        else { //valid
            done = 1;
        }
    }
    printf("\nStudent Sex :%c\n", *sex);
    return *sex; //once you enter valid value, return it...
}

int main() {
    Gender();
}

Also read this about automatic allocation of buffer space, difference between %ms and %s scanf

ChuckCottrill
  • 4,360
  • 2
  • 24
  • 42
  • I am trying it this way char sex; void Gender(){ printf("\nEnter Student Gender (example M for Male F for Female):\n"); scanf(" %c",&sex); switch(sex){ case 'M': case 'm': printf("Student Sex : Male"); break; case 'F': case 'f': printf("Student Sex : Female"); break; default: printf("\n FALSE gender .. please enter M for Male and F for Female:\n"); } } – Angelo Apr 24 '19 at 02:50
  • You gotta use only one of the sexValid functions - I've changed the names to end in 'c' and 's', and guessed which you want... – ChuckCottrill Apr 24 '19 at 04:00