2

I am currently working on an practice. My program is working and I just want to make it more robust and foolproof. The code is of the following:

printf("Enter Name : ");
memset(userinput, '\0', 50);
fgets(userinput, 50, stdin);

I accidentally hit the enter key(newline) and for my program, the system just dangle there and couldn't accept anymore inputs. I am only allowed to use fgets. So is there any way of rejecting \n from being entered as a field?

rollstuhlfahrer
  • 3,988
  • 9
  • 25
  • 38
pandora
  • 21
  • 2
  • 5
    No, `fgets` retains the newline at the end of the input string, and you have to ignore it or [remove it](https://stackoverflow.com/a/28462221/4142924). Please post the [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) which shows what you have tried. – Weather Vane Feb 04 '18 at 21:49
  • 4
    You could check if the first character is a newline and ask again – rollstuhlfahrer Feb 04 '18 at 21:50
  • 1
    If the user hits blank and then newline, you probably don't want to accept that as a name. You might be reluctant to accept "`@#!%%&`" as a name, too. You need to think carefully about what you want from this code. – Jonathan Leffler Feb 04 '18 at 22:13
  • 1
    @JonathanLeffler True, [always sanitize user input](https://xkcd.com/327/) – chux - Reinstate Monica Feb 04 '18 at 23:14

2 Answers2

3

One way you could do it is to check if the first character is a newline:

do {
    printf("Enter Name : ");
    memset(userinput, '\0', 50);
    fgets(userinput, 50, stdin);
}
while ( userinput[0] == '\n'); 

printf("Hello %s", userinput);

This would still leave you up to space + newline, but its a first start.

rollstuhlfahrer
  • 3,988
  • 9
  • 25
  • 38
  • 3
    Note: you don't need the `memset()`. – wildplasser Feb 04 '18 at 22:43
  • 1
    What happens when you press `Ctrl-Z` (Windows) or `Ctrl-D` (Linux-likes) at such a prompt? (Which goes slightly beyond OP's question, but then again OP seems unaware of it.) Add an extra test, other than a plain Return. – Jongware Feb 04 '18 at 23:07
  • 2
    You need to test the return value from `fgets()` to know whether it encountered EOF or an error. You’ll loop forever if it does spot either of those conditions. – Jonathan Leffler Feb 04 '18 at 23:17
0

So is there any way of rejecting \n from being entered as a field?
... to make it more robust and foolproof.

Code should not prevent '\n' from being read via fgets(). Instead, code should assess that input for validity. A leading '\n' is likely only 1 concern. Make code easy to update as certainly the criteria for a valid name will evolve.

I recommend a separate name test.

bool ValidNameInputTest(const char *userinput) {
  if (*userinput == '\n') return false; // fail
  // add other tests as needed
  return true;
}

In a loop, test and repeat as needed. Code should exit the loop on success. When an end-of-file or input error occurs, code should detect/handle that too.

...
char userinput[50];

do {
  printf("Enter Name : ");
  fflush(stdout);   // add to insure above output is seen before reading input
  //memset(userinput, '\0', 50);// Commented out as not needed - although useful for debug

  // Check return value and used a derived size
  //fgets(userinput, 50, stdin);
  if (fgets(userinput, sizeof userinput, stdin) == NULL) {
    Handle_EndOfFile_or_Error();
  }
} while (!ValidNameInputTest(userinput));
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256