The following program calls a function, which prompts the user for input. The function then returns one of three enum constants; INPUT_SUCCESSFUL
, INPUT_TOOLONG
, or INPUT_FAILED
. If successful, it prints the text entered by the user. Otherwise, it prints an error message, and takes the appropriate action.
The function contains three parameters. The first one is a constant character array, which gets passed the text that will be used to prompt the user. The second is a character array, in which the text entered by the user will be placed. And the third is the size of the character array.
I have the following questions...
1) Would it have been better to let the called function handle the printing of error messages, exiting the program, etc, instead of the main function?
2) Would it have been better to pass a pointer to the function so that it could allocate the appropriate memory, instead of passing it a fixed array?
3) Any potential issues with the program or improvements that can be made to the code?
The program was compiled as follows...
gcc -std=c99 -Wall -Wextra -Wpedantic main.c user_input.c
...and received only warnings about unused parameters argc
and argv
. Here are the files...
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "user_input.h"
#define MAX_STR_LEN 50
int main(int argc, char *argv[])
{
char user_input[MAX_STR_LEN + 2]; /* +2 for newline character (\n) and terminating null character (\0) */
input_status status;
while (1)
{
status = get_user_input("Enter your name: ", user_input, sizeof(user_input));
if (status == INPUT_FAILED)
{
fprintf(stderr, "Unable to read user input\n");
exit(EXIT_FAILURE);
}
if (status == INPUT_TOOLONG)
{
fprintf(stderr, "Entry exceeds %d characters\n", MAX_STR_LEN);
continue;
}
if (strlen(user_input) == 0)
{
fprintf(stderr, "Entry is missing\n");
continue;
}
if (user_input[0] == 0x18) /* user entered Ctrl+X (^x) to cancel */
{
fprintf(stderr, "User cancelled\n");
return 0;
}
break;
}
printf("User entered: %s\n", user_input);
return 0;
}
user_input.h
#ifndef USER_INPUT_H
#define USER_INPUT_H
typedef enum
{
INPUT_SUCCESSFUL,
INPUT_TOOLONG,
INPUT_FAILED
} input_status;
void flush_input();
input_status get_user_input(const char *prompt, char *user_input, size_t size);
#endif
user_input.c
#include <stdio.h>
#include <string.h>
#include "user_input.h"
void flush_input()
{
int c;
while ((c = getchar()) != '\n' && c != EOF)
/* skip it */ ;
}
input_status get_user_input(const char *prompt, char *user_input, size_t size)
{
printf("%s", prompt);
if (fgets(user_input, size, stdin) == NULL)
return INPUT_FAILED;
char *pNewline;
if ((pNewline = strchr(user_input, '\n')) == NULL)
{
flush_input();
return INPUT_TOOLONG;
}
*pNewline = '\0';
return INPUT_SUCCESSFUL;
}