0

Have to take a input string of size 5. Also have to check for validity in some unrelated sense. If the input is not valid user is prompted to input again.

Using the scanf("%4s", input); But if the user inputs suppose string of 8 characters, the scanf just scans the last 4 chars still in the buffer before asking for actual user input.

I tried making a buffer variable that stores the input before passing it to the target var.

2

2 Answers 2

2

How to prevent buffer overflow when we recursively ask for input if input is not valid?

  1. When seeking an input of up to n characters, (which is n + 1 characters when one counts the Enter or '\n'), read at least a line of at least n + 1 characters. With fgets(), that needs to fit in a buffer of size n + 2. The extra 1 is to store the appended null character.
#define STRING_LENGTH_MAX 5

char buf[STRING_LENGTH_MAX + 2];
for (;;) {
  if (fgets(buf, sizeof buf, stdin) == NULL) {
    // There is no more input from stdin.
    // TBD code - perhaps quit?
  }
  ...
  1. Search the string saved for a '\n'. If found, lop it off and continue. If not found and line is long, read the rest of the line. Discard all and loop back (not recurse) to step 1.
  buf[strcspn(buf, "\n")] == '\0'; // Lop off a potential '\n'.
  if (strlen(buf) <= STRING_LENGTH_MAX) {
    // Perform other validation tests on `buf`.
    // Otherwise ...
    break;
  }
  // Read and toss rest of line.
  int ch;
  while ((ch = getchar()) != '\n' && ch != EOF) {
    ;
  }
}
  1. Consider putting this all into a helper function.
Sign up to request clarification or add additional context in comments.

2 Comments

Define the buffer with a much bigger length — such as #define STRING_MAX_LENGTH 2048. Then deal with any overlength (or underlength) strings that are entered. The chances are high that you won't get a partial line this way.
@JonathanLeffler Yes a larger buffer reduces the chances of the need for while ((ch = getchar()) != '\n' && ch != EOF) clean-up - yet does not eliminate it. As a rule-of-thumb, when a buffer of n is the expected max, I code for 2*n.
0

Simple: always get a full line of text from the user (using fgets()).

If the user does not give you a full line of text, then the input is invalid; either complain and abort, or discard input until you find that newline and ask again.

This is because of a simple principle:

⟶ The user will always press Enter at the end of every asked input ⟵

Once a full line of text is obtained, then attempt to convert it to int or whatever.

3 Comments

"The user will always press Enter at the end of every asked input" --> this is certainly common. Other potentials: 1) Input is closed - there is no final '\n'. e.g. input was "abc" and then end-of-file was signaled without a '\n'. 2) Rare: input has an input error.
Both of those can be considered abnormal responses (and thus, erroneous) to things like “What is your age? ”. If the TTY asks you a question, it is always expected to type an answer and then press Enter to ratify it. Piped processes or files pretending to be humans in this context should also be expected to answer as a human; a file ending without a newline counts as error here.
I could see going that way. Yet in my experience, I found tolerating input that ended with end-of-file (and not obliging a '\n') made the software more useful and less maintenance. Your call.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.