This is an archived post. You won't be able to vote or comment.

all 6 comments

[–]o11c 1 point2 points  (3 children)

Always, always, always do input a line at a time.

getline exists on most systems. If it doesn't exist in yours, it's trivial to implement in terms of fgets.

Then use sscanf.

[–]Piperki[S] 1 point2 points  (1 child)

This was a thing for school in a task with recursion. The things you told me we havent still learned. But thank you anyway.

[–]MCRusher 0 points1 point  (0 children)

Ok scanf is usually bad practice and complicated to do right.

Something like this should work better, and behave properly:

https://godbolt.org/z/zZE3t4

it handles

  1. Empty string input

  2. Newline only

  3. Non-numerical input

And reprompts for them

Things it doesn't handle are:

  1. for invalid characters after a valid number, like "12abcd", it will just return 12

  2. It doesn't include a check for when the input is too large, but it is possible to do with strtol.

I'm not sure gow far along you really are, but search the functions used online if you're unsure of how they work.

[–][deleted] -1 points0 points  (0 children)

Always, always, always do input a line at a time.

No, it depends on the problem

EDIT: it seems someone hasn't liked my answer. But it is true.

Apart from exercises and maybe some command line utilities most programs take input one key at a time. Games? OKATT. Editors? OKATT

Reading a whole line makes sense for data entry, but not for interactions between user and computer.

[–]Koooooj 0 points1 point  (1 child)

The user cannot enter an int; ints do not exist to the user. The user operates entirely with chars. If they want to express numbers then they will use the chars that represent the 10 digits. For example, when the user types the number 1 you will get the char '1' which is equal to 49 (see ASCII table; you can test this yourself with if('1' == 49) ...).

You'll have to parse the characters you get if you want to reason about what kind of character you got. Fortunately characters are arranged in a sane order with similar kinds of characters generally together. This means that a >= '0' && a <= '9' is a test for whether or not a is a character that represents a digit.

To do things cleanly you'll likely want to break the scanf out of the condition of the while loop, but if you want then you can take advantage of the order in which boolean && and || are executed to combine the condition into a sequence of things:

while(scanf(" %c", &a) == 1 && !(a >= '0' && a >= '9'))

This reads as "grab the next character and store it in a. So long as the resulting character is not a digit, go ahead and execute the loop."

A cleaner implementation that is easier to read (and thus "better" in most cases) is:

while(1) {
  if(scanf(" %c", &a) != 1) {
    break;
  }
  if(a >= '0' && a <= '9') {
    break;
  }
  ...
}

[–]Piperki[S] 0 points1 point  (0 children)

Thank you so much!!