Search code examples
carraysswitch-statementgetchar

How to read a single character with getchar in C?


I'm creating a menu driven program in C where I have to ask for user input, then use only the first character of the input in my program. In addition to the code below, I've also tried #define MAX_CHAR 1 and using it instead of EOF in the while loop, among other things.

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

void print_menu();
void uppercase(char *string); 

int main()
{
    char i = 0, c = 0;
    char selection[0];

    print_menu();

        while((c = getchar()) != EOF)  
        {
            selection[i++] = c;
            selection[i] = '\0';  //insert NULL at end of string
            uppercase(selection);

            switch(selection[i])
            {
                case 'c':
                uppercase(selection);
                printf("%s\n", selection );
                print_menu();
                break;

                case 'X':
                printf("The program is exiting, Schuss!\n" );
                exit(0);

                default:
                printf("\nYou entered: %s\n", selection);
                print_menu();
                break;
           }

        }
 return 0;
}

void print_menu()  //gives code for menu
{
    printf("Select a menu item and hit enter: \n" );
    printf("C)  Convert the string to uppercase\n");
    printf("M)  Display this menu\n");
    printf("X)  Exit the program\n");
}
void uppercase(char *string) 
{
  int c = 0;

  while (string[c] != '\0')
  {
    if (string[c] >= 'a' && string[c] <= 'z')
    {
      string[c] = string[c] - 32;
     }
     c++;
  }

}

If I type Yes! when running the program, I expect the output to be You entered: Yand then the menu prints. Currently the output is

You entered: Y
Select a menu item and hit enter: 
C)  Convert the string to uppercase
M)  Display this menu
X)  Exit the program

You entered: YE
Select a menu item and hit enter: 
C)  Convert the string to uppercase
M)  Display this menu
X)  Exit the program

You entered: S
Select a menu item and hit enter: 
C)  Convert the string to uppercase
M)  Display this menu
X)  Exit the program

You entered: S!
Select a menu item and hit enter: 
C)  Convert the string to uppercase
M)  Display this menu
X)  Exit the program

You entered: 

Select a menu item and hit enter: 
C)  Convert the string to uppercase
M)  Display this menu
X)  Exit the program
^C

I'm pretty sure it's a problem with the while loop, haven't figured out how to fix it though. Eventually I'll have more menu items and cases. So for example, the user will enter A and it'll print a then print the menu again to wait for the next menu selection until the user enters 'X' to exit. Also, I do know there are two function calls for uppercase and that's intentional at this point.

EDIT: I'm wanting getchar() to read one character as it's designed to do. Then do whatever matches the case for that character. Then print the menu again (this part is included in each case statement). Then repeat from step 1 (which is "read one character").

I've changed my code to put getchar() outside the while loop and set the loop to while(1) instead which does result in reading only one character but also creates an infinite loop printing You entered: B and the menu. So that's progress, kind of.


Solution

  • How to read a single character with getchar in C?

    You can read ONLY a single character using getchar.

    I have to ask for user input, then use only the first character of the input in my program.

    You can do that by reading an entire line and using only the first character of the line.

    char line[100]; // Make it large enough.
    while( fgets(line, 100, stdin) != NULL )
    {
        uppercase(line);
        char selection = line[0];
    
        switch (selection)
        {
           ...
        }
    }