Question

I'm really confused about the usage of getchar() and scanf(). What's the difference between these two?

I know that scanf() [and family] get a character by character from the user [or file] and save it into a variable, but does it do that immediately or after pressing something (Enter)?

and I don't really understand this code, I saw many pieces of code using getchar() and they all let you type whatever you want on the screen and no response happen, but when you press enter it quits.

int j, ch;

printf("please enter a number : \n");

while (scanf("%i", &j) != 1) {
    while((ch = getchar()) != '\n') ;
    printf("enter an integer: ");
}

Here in this code can't I use scanf() to get a character by character and test it? Also, what does this line mean?

scanf("%i", &j) != 1

because when I pressed 1 it doesn't differ when I pressed 2? what does this piece do?

and when this line is gonna happen?

printf("enter an integer: ");

because it never happens.

Was it helpful?

Solution

Well, scanf is a versatile utility function which can read many types of data, based on the format string, while getchar() only reads one character.

Basically,

char someCharacter = getchar();

is equivalent to

char someCharacter;
scanf("%c", &someCharacter);

I am not 100% sure, but if you only need to read one character, getchar() might be 'cheaper' than scanf(), as the overhead of processing the format string does not exist (this could count to something if you read many characters, like in a huge for loop).

For the second question.

This code:

scanf("%i", &j) != 1

means you want scanf to read an integer in the variable 'j'. If read successfully, that is, the next input in the stream actually is an integer, scanf will return 1, as it correctly read and assigned 1 integer.

See the oldest answer to this SO question for more details on scanf return values.

OTHER TIPS

As far as I understand, the getchar function will read your input one character at a time. scanf will read all types of data, and will be more useful to define a data group. However, as far as strings go, my teacher recommends using gets instead of scanf. This is because scanf will stop 'getting' the data at the first white space you put in, like in a sentence...

while (scanf("%i", &j) != 1) {
    while((ch = getchar()) != '\n') ;
    printf("enter an integer: ");
}

Here's how this code breaks down.

  1. scanf() consumes individual characters from the input stream until it sees a character that does not match the %i conversion specifier1, and that non-matching character is left in the input stream;
  2. scanf() attempts to convert the input text into a value of the appropriate type; i.e., if you enter the string "1234\n", it will be converted to the integer value 1234, the converted value will be assigned to the variable j, and the '\n' will be left in the input stream;
  3. if there are no characters in the input string that match the conversion specifier (such as "abcd"), then no conversion is performed and nothing is assigned to j;
  4. scanf() returns the number of successful conversions and assignments.
  5. if the result of the scanf() call is not 1, then the user did not enter a valid integer string;
  6. since non-matching characters are left in the input stream, we need to remove them before we can try another scanf() call, so we use getchar() to consume characters until we see a newline, at which point we prompt the user to try again and perform the scanf() call again.


1. The %i conversion specifier skips over any leading whitespace and accepts optionally signed integer constants in octal, decimal, or hexadecimal formats. So it will accept strings of the form [+|-]{0x[0-9a-fA-F]+ | 0[0-7]+ | [1-9][0-9]*}

The scanf can scan arbitrarily formatted data and parse it as multiple types (integers, floating point, strings, etc). The getchar function just gets a single character and returns it.

The expression

scanf("%i", &j) != 1

reads a (possibly signed) integer from the standard input, and stores it in the variable j. It then compares the return value of the scanf function (which returns the number of successfully scanned conversions) and compares it to 1. That means the expression will be "true" if scanf didn't read or converted an integer value. So the loop will continue to loop as long as scanf fails.

You might want to check this scanf reference.

That the printf doesn't happen might be either because it never happens (use a debugger to find out), or it just seemingly doesn't happen but it really does because the output needs to be flushed. Flushing output is done either by printing a newline, or with the fflush function:

fflush(stdout);

As far as I know, scanf will read user input until the first whitespace, considering the input format specified. getchar, however, reads only a single character.

scanf will return the number of arguments of the format list that were successfully read, as explained here. You obtain the same result when pressing 1 or 2 because both of them are successfully read by the %i format specifier.

getchar reads one char at a time from input. where as scanf can read more depending upon the data type u specify.

its not good practice to use scanf() try using fgets(), its much more efficient and safe than scanf.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top