So far, we have talked about how the scanf() function reads input in a straightforward way. However, the input may not be provided in the form expected from the user. It might be in a different format, as we will see soon. In such cases, how does scanf() know if the input is an integer or a floating-point number?
There are certain rules that the scanf() function follows to identify integers and floats. But before we delve into those rules, let’s first talk about how scanf() handles spaces and other whitespace characters in the input.
Reading Whitespace Characters in the Input
The scanf() function simply ignores any whitespace characters, such as spaces, tabs, and newlines, in the input sequence.
Let’s consider the following example of a scanf() function call:
scanf(“%d%f%d%d”, &p, &q, &r, &s);
And let’s say the input sequence is:
-1 10.33
-25
-98
Even though the input sequence has spaces, tabs, and newlines, the scanf() function will ignore them. It will only read the specific values and store them in the respective variables p, q, r, and s. Assuming that p, r, and s are integer variables, and q is a float variable, the values will be as follows:
p = -1, q = 10.33, r = -25, and s = -98
But what if the above sequence is entered by the user without any whitespace characters, like this:
-110.33-25-98
In this case, it becomes more complicated. We need to understand how scanf() recognizes integers and floats in a sequence, along with the concept of buffer storage.
Buffer Storage
When input is provided to the program, it doesn’t immediately read it character by character. Instead, it stores the input in a hidden buffer, which the scanf() function can access directly. This buffer acts as a temporary storage space where the entered input is held.
In the case of the input sequence -110.33-25-98, the buffer storage would look like this:
Note that the \n is a newline character added at the end of the buffer because the user will surely press enter after providing the input sequence.
Rule to Recognize Integers
There’s a simple rule that scanf() follows to identify integers. When reading the input sequence from the buffer, it checks if the first character is a digit, plus sign, or minus sign. Then, it continues reading the characters until it encounters a non-digit character.
For example, let’s consider the same scanf() function with four different inputs and the same buffer.
scanf(“%d%f%d%d”, &p, &q, &r, &s);
In the format string, the first specifier is %d, which means that scanf() is expecting to find an integer in the buffer and store it in the variable p. Now, let’s look at the characters in the buffer: -110.33-25-98.
The first character in the buffer is the minus sign, which is acceptable for an integer. Then, scanf() continues reading the next characters: 1, 1, 0. These are also digits and therefore accepted. However, when it reaches the fifth character, which is a decimal point (non-digit), scanf() knows that it has reached the end of the integer. It puts the decimal point back into the buffer and considers the integer portion, -110, as the value for the variable p.
So, the final result is: p = -110.
And, the current state of the buffer looks like the following:
Rule to Recognize Floats
When scanf() is instructed to read a floating-point number based on the format specifier, it follows a specific rule. It looks for an optional plus sign, an optional minus sign, and a sequence of digits (which may include a decimal point). It may also look for an optional letter ‘e’ or ‘E’, followed by an optional sign and one or more digits.
Let’s consider the example scanf() call:
scanf(“%d%f%d%d”, &p, &q, &r, &s);
After reading the first input, scanf() moves on to the %f specifier, which indicates that it should read a floating-point number. Let’s assume the current state of the buffer is as follows:
Now, the scanf() function will encounter the decimal point ‘.’ after the minus sign. It recognizes that the decimal point is valid for a floating-point number. Next, it picks the next two digits, ‘3’ and ‘3’. However, when it encounters the next character, ‘-‘, it realizes that it is not a valid character for a floating-point number. In this case, scanf() puts the ‘-‘ character back into the buffer and considers the accepted floating-point number for the variable q as 0.33.
So, the final result is: q = 0.33 and the current state of buffer looks like the following:
Problem for You to Solve
The scanf() function has not finished reading the entire input. Let’s take a look at the current state of the buffer
and the scanf() function:
scanf(“%d%f%d%d”, &p, &q, &r, &s);
Your task is to determine the values stored in the variables r and s after the scanf() function reads the complete buffer. As a bonus, can you guess what happens to the newline character \n at the end of the buffer?
Solution:
In the given format specifier "%d%f%d%d", the next specifier is %d. So, scanf starts picking characters from the buffer. It first picks the minus sign ‘-‘, which is a valid character for an integer. Next, it picks the digits 2 and 5. However, when it encounters another minus sign ‘-‘, it recognizes that it is not a valid character for an integer after the digits 2 and 5. Therefore, scanf puts the minus sign back into the buffer. As a result, the value stored in variable r is -25. The current state of the buffer is as shown:
Moving on, the final specifier is %d. scanf reads the remaining characters in the buffer, which are -98. It recognizes that the newline character \n is not a valid character for an integer, so it puts it back into the buffer. Hence, the value stored in variable s is -98. The current state of the buffer is shown below:
Since we don’t have any more specifiers to process, the newline character \n remains in the buffer. It will be processed by the next scanf call (if any).
So, the final values are: p = -110, q = 0.33, r = -25, and s = -98.
Just a quick note: You might be wondering why we’re only focusing on integers and floats when there are other types like characters and strings to consider. The reason is that we want to explain how scanf() works in a thorough manner, and it’s simpler to start with integers and floats for now. As we continue with this course, we’ll also cover the other types and how they behave differently with the printf() and scanf() functions.
Leave a comment