Scanf exercise implementation
In this article, let’s do a scanf exercise. The exercise is, Write a program which takes 3 numbers from the user. And the program should compute the average of those numbers, and the result must be printed.
Now let’s create a new project. Here we are creating a project for our PC, not for the embedded board. So, select the C/C++ project.
Let’s give the name Average.
Then, let’s create a new source file. Right-click on Project, select New, and select Source File.
Let me name it main.c.
First, let’s create a variable. Let’s create 3 variables. float number1, number2, number3; Users may enter a real number, which is also possible. So, let’s take a float here. And now, let me also create another variable. float average; To store the average value.
After that, now let’s first ask the user to enter the first number. Printf(“Enter the first number:”); Let me not give \n here. So, let a user enter after this colon. I would give this message “Enter the first number” so the cursor will not move to the next line; rather it will just stick at this position.
Now, let’s use the scanf function. Let’s first mention the format specifier “%f”; after that, let’s give a comma, and then give the address of the first variable number1. After that, let’s repeat these two statements for the second and third numbers.
After that, let’s compute the average. Then print the average. The code is shown below.
#include <stdio.h> int main(void) { float number1, number2, number3; float average; printf("Enter the first number: "); scanf("%f",&number1); printf("\nEnter the second number: "); scanf("%f",&number2); printf("\nEnter the third number: "); scanf("%f",&number3); average = (number1 + number2 + number3) / 3; printf("\nAverage is : %f\n",average); }
Then, let’s build this project. It was built successfully, and let’s run. Now we can see that(Figure 5) when you try to run the application, the Average.exe runs, but the first message is not getting printed. Now the reason for that is “Enter the first number” this message is not reaching the console. That means this message is actually buffered inside the operating system. So, that is not pushed or flushed to the console. So, problems like this you may encounter when you use a different console. Here we are using the Console of an eclipse software. So, there may be console buffering.
When you execute printf, what happens is that the content will not be pushed directly to the Display. It is actually buffered inside the output buffer. So, this is actually a software buffer.
When your application returns, the content of the output buffer will be automatically flushed to the display. But in our program what’s happening is, we are waiting for the user input. So, there is no trigger for the output buffer to flush the contents to the display. In the earlier program we were returning from the function. So, there was a trigger to flush the contents of the output buffer to the display. So now, here we have to give explicit command for the output buffer to flush the contents to the display.
Now we do that by using a function called fflush. fflush is actually an API which is used to clear the output buffers of the output stream. When you use fflush, the contents of the output buffer will be flushed to the display.
Let’s use this fflush. Here, write after the printf statement. fflush(stdout); The argument you have to pass here is that stdout, which is standard output, is flush to the standard output.
Usage of fflush is to flush the contents of the output buffer to the stdout. Its usage also depends on the type of console you use. Here we are displaying on the console of ‘eclipse’ software. When you execute the .exe on windows command prompt, fflush may not be required.
int main(void) { float number1, number2, number3; float average; printf("Enter the first number: "); fflush(stdout); scanf("%f",&number1); printf("\nEnter the second number: "); fflush(stdout); scanf("%f",&number2); printf("\nEnter the third number: "); fflush(stdout); scanf("%f",&number3); average = (number1 + number2 + number3) / 3; printf("\nAverage is : %f\n",average); }
Let’s run this program. Now we are getting the message “Enter the first number”. Here, you can see that this eclipse console is not showing you the cursor(Figure 7). That’s a problem.
Now you can click here in the Console. Let me type the first number as 3.5, and let’s hit enter. Let me type the second number as 2.5 and enter the third number as 3. Let’s hit enter. And here you can see that it shows you the average result is 3, as shown in Figure 8. That is correct.
You can see that it is actually showing the cursor here. So, that is not correct.
So, this eclipse console is not that great. Instead of using this, you can directly execute Average.exe as a windows application.
For that, you have to go to its path. Right-click on the project, and go to properties. And in the resource tab, you can see this icon(Show in System Explorer), just click that, and it will open the project workspace.
Go inside Average, go inside Debug, and you can directly launch this Average.exe.
Now let’s launch this application, just double click on Average.exe, and here you can see that this looks good because it is actually showing you the correct cursor position for you to enter the number.
Enter some numbers. Let me enter 45, 10, -9888 and press enter. Here you can see that the console is exited(Figure 12). We couldn’t be able to see the result.
That’s because in the program after you print the average, this code exits. That’s actually the completion of the application. That’s why the console exited. So, we couldn’t be able to observe the result.
Let’s implement some logic in the program so that your program hangs after printing the result. For that, we can make the application wait until the user presses any key from the keyboard. That means let’s use getchar() here. So, let me use the getchar() API. This API waits until the user presses any key from the keyboard. Now let me just call getchar(). That means to get a character from the keyboard. So, until the user enters a character, this API waits. Let’s test this.
int main(void)
{
float number1, number2, number3;
float average;
printf("Enter the first number: ");
fflush(stdout);
scanf("%f",&number1);
printf("\nEnter the second number: ");
fflush(stdout);
scanf("%f",&number2);
printf("\nEnter the third number: ");
fflush(stdout);
scanf("%f",&number3);
average = (number1 + number2 + number3) / 3;
printf("\nAverage is : %f\n",average);
getchar();
}
Let’s see whether our application waits for the user input or not before it exits. Let me launch once again.
Now, it doesn’t wait, and again the console is exited. So now, we have to understand what exactly is going on here. So, it didn’t wait here.
Let’s understand the relationship between the keyboard, input buffer, and the program.
a. Now, whatever you enter from the keyboard, it doesn’t come to the program directly. It actually goes to the Input buffer.
b. For example, we are scanning for the first number. Let’s say you enter 10, and after that, you hit enter.
c. Once you do that at the keyboard side, those two data(10\n) will come to the input buffer. Now the input buffer has two different data. One is a number that you enter, that is 10, and another one is the new line character, so that is your enter key, so that is also stored in the input buffer.
Once it comes to the input buffer, scanf actually reads the data. In this case, the scanf should read one real number. So, we want to read a real number. That’s why we specified the format specifier %f. So,10\n this data will be read from the scanf. So, we have instructed scanf just to read one data because there is only one format specifier.
d. Once scanf reads that, this will be the state of the input buffer. So now \n is remaining in the input buffer. So, that is unread data.
e. After that, you want to execute the second scanf. Once you make a call to the second scanf, what happens? So, this \n (that is a special character, the new line character) will be read and discarded by the scanf because it’s not a valid number but a special character. So, scanf waits for the new user input.
f. After that, let’s say the user enters a new number followed by the enter key. So, scanf will read this number 45.
g. And after that, you execute the final scanf for the number 3. This time the input buffer contains 65 and a new line character(\n). So now, 65 will be read by the scanf.
h. After that, this is the final state of the input buffer after 3 scanf’s in the program. So, there is data which is still there in the input buffer.
After that, what we are doing in the program is calculating the average, and then we are printing the average, and after that, we use getchar().
So, this time, getchar () doesn’t wait for the user input. Because getchar() goes and fetches whatever the data is there in the input buffer. So, getchar() fetches \n and it returns. That’s the behavior of the getchar(). Whenever it encounters a new line character, the getchar() returns immediately. So, that is the behavior of that API. That’s why getchar() fetches \n, and it returns. So, that’s why our application didn’t wait, so it exited immediately.
How to solve this issue?
One thing is you can give getchar() twice here. So now, you can solve this problem by giving getchar() twice. This is actually not a generic solution, but just to see the effect. You can give getchar() twice here, and you can give one message to the user saying “press enter key to exit the application,” as shown in Figure 17.
Let’s try.
Now here you can see that the application is waiting because of that second getchar(), and if you press the enter key, the getchar() immediately returns, and the application exited.
That is not a generic solution. I would use a while loop here. Don’t worry, I have not yet covered the while loop, so you will understand this code after I cover the looping in ‘C.’
average = (number1 + number2 + number3) / 3;
printf("\nAverage is : %f\n", average);
printf("Press enter key to exit the application \n");
while(getchar() != '\n')
{
}
getchar();
}
I write while(getchar() != ‘\n’).
I just loop here until I read every data from the input buffer. After that, at the end, I again wait for the user input, so give getchar();
Let’s just test this.
The average is shown in Figure 22. You can cross-check this with your calculator and then press enter key to exit the application.
In the following article, let’s use only one scanf to read all the 3 numbers instead of using three scanf functions.
FastBit Embedded Brain Academy Courses
Click here: https://fastbitlab.com/course1