Dealing with Ordinary Characters

In the last tutorial, we learned how scanf() recognizes integers and floats. We only saw the format string of the scanf() function with format specifiers, but in reality it need not be like that. The scanf() function can accept ordinary characters in the format string, just like printf(), but it behaves a little differently than printf() when it encounters these characters. In this tutorial, we will dive deeper into how scanf() treats ordinary characters in the format string. Let’s begin!


Introduction

We know the printf() function can accept any character in the format string and it displays those characters as they are.

#include <stdio.h>

int main() {
    int a = 10, b = 20, sum;
    
    sum = a + b;
    
    printf("Sum: %d", sum);
    return 0;
}

Output:

Sum: 30

During execution, %d is replaced by the value of the variable sum, which is 30. The ordinary characters forming the string “Sum: “ are displayed as they appear.

The job of the printf() function is straightforward—display the ordinary characters as they appear. But, what about the scanf() function?

Up to now, we were dealing with the scanf() function that looks more or less the same as shown:

scanf("%d%f", &a, &b);   // assuming a is an integer variable and b is a float variable

The format string is simple as it only contains format specifiers. It can accept an integer and a float separated by any number of whitespace characters (as mentioned in the last tutorial, scanf() skips whitespace characters especially when inputs are integers or floats). This seems fair enough!

But, what if a whitespace character (like a space) is introduced between the format specifiers? Does that mean scanf() will force the user to enter a whitespace character as part of the input? What about non-whitespace characters? Let’s understand these situations properly in the coming sections.


Handling Whitespace Characters

Adding a whitespace character (i.e., a space, a newline, or a tab) between format specifiers does not enforce a whitespace character as the input. For integers and floats, the whitespaces are simply ignored by scanf(). So, there is absolutely no difference between the following versions of the scanf() function:

scanf("%d%f", &a, &b);
scanf("%d %f", &a, &b);    // format specifiers with a space
scanf("%d\n%f", &a, &b);   // format specifiers with a newline
scanf("%d\t%f", &a, &b);   // format specifiers with a tab

Adding a whitespace character in the format string tells the scanf() function to skip any amount of whitespaces entered by the user until a non-whitespace character is found. The same functionality can be achieved without specifying a whitespace character.

If we add whitespaces between the format specifiers, then readability improves because of the clear separation between format specifiers.

Is readability the only benefit we get? No. For character inputs, whitespaces in the format specifiers are quite useful for ignoring whitespaces in the input. Consider the following scanf() function:

scanf("%d%c", &a, &b); 

Let’s say the user input is: 10 d.

As 10 is an integer, the scanf() will put it inside the variable a. Then, it encounters a whitespace. A whitespace is a character which scanf() function accepts because of the second format specifier %c. The variable b will have a space, and as scanf() has exhausted all format specifiers, the next input ‘d’ is put back in the buffer to be read by the next scanf() call. So, normally, scanf() reads a whitespace character for a character variable.

To avoid reading a whitespace character, you can add a whitespace between the format specifiers as follows:

scanf("%d %c", &a, &b);

Because of the space between %d and %c, all whitespaces will be ignored after reading an integer. Only a non-whitespace character will go inside variable b.


Handling Ordinary Characters

What about non-whitespace characters? Any non-whitespace character in the format string is treated as a literal. The scanf() function tries to find the exact match in the input. If the exact match is found, it will be skipped, otherwise scanf() stops reading the input.

Let us assume we want that the user should provide the input in the following format:

10, 20

To accept the input as stated, the scanf() function should look like the following:

scanf("%d, %d", &a, &b); // considering a and b are integer variables defined before the scanf() call.

Note that the space after the comma in the format specifier shown above is optional, but adding it improves readability.

Because of the first %d, scanf() looks for an integer. After that, it expects a comma (the comma must appear immediately after the integer; space followed by a comma is not accepted). If it encounters a comma, it will skip it. The scanf() will also skip any number of whitespace characters (due to the space added after comma in the format string) until it encounters the second integer.

So, the following input is accepted:

10, 20

But not this one:

10 , 20

Summary

  • Whitespace in the format string → skips any amount of whitespaces in the input.
  • Non-whitespace characters in the format string → looks for an exact match and then skips it. If no match, then reading stops.
  • Most format specifiers skip leading whitespaces, but %c does not until you add a space before them in the format string.


Leave a comment

Leave a comment

Your email address will not be published. Required fields are marked *

Thank you for choosing to leave a comment. Please be aware that all comments are moderated in accordance with our policy. For more information, please review our comments policy. Rest assured that your email address will not be shared with anyone. Kindly refrain from using keywords in your comment. Let’s maintain a respectful atmosphere and engage in meaningful conversations.