Difference between revisions of "ES101 - Lesson 3 : scanf"

From Embedded Systems Learning Academy
Jump to: navigation, search
(scanf)
(Common Mistake)
 
(12 intermediate revisions by one other user not shown)
Line 6: Line 6:
 
** CR/LF Enable
 
** CR/LF Enable
 
** Local Echo
 
** Local Echo
 +
*  Anything typed inside '''Hercules''' window will be transmitted to the board.
  
 +
<br/>
 
'''scanf''' syntax is similar to '''printf''', but it scans for input.  The specifier list is the same, and one or more inputs can be captured similarly to how you use '''printf'''. Let's start with a code example:
 
'''scanf''' syntax is similar to '''printf''', but it scans for input.  The specifier list is the same, and one or more inputs can be captured similarly to how you use '''printf'''. Let's start with a code example:
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
int age;
+
int age = 0;
float height;
+
float height = 0;
  
 
printf("What is your age? ");
 
printf("What is your age? ");
Line 24: Line 26:
 
* '''scanf''' variables after the double quotes have & symbol.
 
* '''scanf''' variables after the double quotes have & symbol.
  
The & (ampersand) symbol is needed because it is called the address operator. Instead of passing the variable's value, you pass the variable's address such that scanf can input the data into the memory location given by the variable's address. If you forget to include the & operator, you will experience unexpected results because '''scanf''' would probably input the data at the wrong memory location.
+
The & (ampersand) symbol is the '''address''' operator. Instead of passing the variable's value, you pass the variable's address such that scanf can input the data into the memory location of the variable's address. If you forget to include the & operator, you will experience unexpected results because '''scanf''' would probably input the data at the wrong memory location.
  
'''scanf''' should be intuitive to understand except when you try to scanf a single character (%c).  What happens is that a previous '''scanf''' does not consume the <Enter key> character (0x0A) and the next '''scanf''' picks up this character when you try to use: <code>scanf("%c", &my_char);</code>.  To solve this problem a call to getchar() is made, which discards this unconsumed hanging character, and '''scanf''' will wait for a new character from '''Hercules''' terminal.
+
'''scanf''' should be intuitive to understand except when you try to scanf a single character (%c).  What happens is that a prior '''scanf''' does not consume the <Enter key> character (0x0A) and the next '''scanf''' picks up this character when you try to use: <code>scanf("%c", &my_char);</code>.  To solve this problem a call to getchar() is made, which discards this unconsumed hanging character, and '''scanf''' will wait for a new character from '''Hercules''' terminal.
  
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
int age;
+
int age = 0;
char my_char;
+
char my_char = 0;
  
 
printf("What is your age? ");
 
printf("What is your age? ");
Line 37: Line 39:
  
 
/**  
 
/**  
  * This code will not function unless you insert:
+
  * This code will completely skip over the prompt.
  * getchar(); before the next scanf() statement
+
  * If you insert getchar(); *twice* before the next scanf() statement,
 +
* then it will work as expected as the 'dangling' <enter key> characters
 +
* will be discarded and scanf will be forced to look for new input.
 
  */
 
  */
 
printf("Press any key: ");
 
printf("Press any key: ");
Line 45: Line 49:
 
printf("You entered: %c which is the number %u\n", my_char, my_char);
 
printf("You entered: %c which is the number %u\n", my_char, my_char);
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
<br/>
 +
=== Common Mistake ===
 +
Your code is executed sequentially so do not try to assign variables before asking for input:
 +
<syntaxhighlight lang="c">
 +
int weight_lb = 0;
 +
int weight_kg = weight_lb * 1.6; // <-- Assigning this too early!
 +
 +
printf("What is your weight in lb? ");
 +
scanf("%i", &weight_lb);
 +
 +
printf("Your weight in kg: %i\n", weight_kg);
 +
</syntaxhighlight>
 +
  
 
<br/>
 
<br/>
  
 
== Assignment ==
 
== Assignment ==
To provide input to your Board from your computer's PC, you need to open Hercules Program at 38400bps by going to the Serial Tab. Then, you need to open the COM Port and right click anywhere on the middle of the screen and turn on Local Echo. Finally, you can simply type on the screen and hit the Enter key to enter text from your keyboard, which will be transmitted to the Board. Also note that after you open the COM Port in Hercules, the reset button should be pressed on the Board to restart the program.
+
You should setup Hercules to make sure you can provide input to the board correctly :
 +
To provide input to your Board from your computer's PC, you need to open '''Hercules''' Program at 38400bps by going to the Serial Tab.
 +
*  Right click on the serial window and make sure "CR/LF" and "Local Echo" are checked.
 +
*  To enter input, you can simply type on the '''Hercules''' window and hit the <Enter key> to enter text from your keyboard, which will be transmitted to the Board.
 +
Also note that after you open the COM Port in Hercules, the reset button should be pressed on the Board to restart the program otherwise you might miss the output if you open the COM port too late.
  
# Declare four variables and choose their appropriate type, such as int, or float. Use a meaningful name based on the following uses:
+
'''Note for future labs''' :
#* A variable to store the age (in years) of the user
+
<BR/>
#* A variable to store the age in months.
+
Normally, your future labs will build on previous labs. In case you want to preserve your old code, just rename the old '''main()''' function to something earlier such as '''lab3''' and write a new '''main''' function. '''Note that there can only be ONE main() function per program.'''
#* A variable to store the height in inches of the user.
 
#* A variable to store the height in centimeters.
 
# Ask the user to input their age in years and store it to your age variable.
 
# Ask the user to input their height and store it to your height variable in inches.
 
# Calculate the age in months and store it to the appropriate variable.
 
# Calculate the height in centimeters (2.54 cm per inch) and store it to the appropriate variable.
 
# Output the user's age in months and years, height in inches, and height in centimeters.
 
#* The height in centimeters should only display 2 decimal digits.
 
  
 +
<BR/>
 +
We will improve the percentage calculator by allowing a user to input values for us:
 +
#  Declare the following float variables :
 +
#*  Maximum exam score, user's exam score, and percentage.
 +
#  Ask the user to input data into your variables, such as:
 +
#*  "What is the max score of your exam: "
 +
#*  "What was your score: "
 +
# Calculate the percentage and print it out with output similar to:
 +
#*  "You got 45/50 and your percentage is: 90.0%"
 +
# Display "Program finished, press any key to quit ..."
 +
#: Test to be sure that the program quits only when a user presses a key.
 +
#: Print out the key user pressed: '''"You pressed Q to quit the program"'''
 +
 +
<br/>
 
=== Questions ===
 
=== Questions ===
*  After completing the assignment, try removing & symbol for the scanf statement that asks for user's height.   
+
*  After completing the assignment, try removing & symbol for one of the scanf statements.   
 
*: What is the program output?  Does it work as expected?
 
*: What is the program output?  Does it work as expected?
*  Try getting a single character at the end of your program and simply output what the user inputs.
 
*:  Does the program work as expected?
 

Latest revision as of 21:53, 11 November 2019

scanf

The scanf function can be used to input information to your program variables. Here is an overview:

  • Compile and load your program
  • Open Hercules and go to Serial tab.
  • Right click in the middle of the screen and double check the following items are checked:
    • CR/LF Enable
    • Local Echo
  • Anything typed inside Hercules window will be transmitted to the board.


scanf syntax is similar to printf, but it scans for input. The specifier list is the same, and one or more inputs can be captured similarly to how you use printf. Let's start with a code example:

int age = 0;
float height = 0;

printf("What is your age? ");
scanf("%i", &age);

printf("What is your height? ");
scanf("%f", &height);

Notice the following differences and similarities of scanf vs.printf

  • scanf uses same specifiers,%i,%f etc.
  • scanf variables after the double quotes have & symbol.

The & (ampersand) symbol is the address operator. Instead of passing the variable's value, you pass the variable's address such that scanf can input the data into the memory location of the variable's address. If you forget to include the & operator, you will experience unexpected results because scanf would probably input the data at the wrong memory location.

scanf should be intuitive to understand except when you try to scanf a single character (%c). What happens is that a prior scanf does not consume the <Enter key> character (0x0A) and the next scanf picks up this character when you try to use: scanf("%c", &my_char);. To solve this problem a call to getchar() is made, which discards this unconsumed hanging character, and scanf will wait for a new character from Hercules terminal.


int age = 0;
char my_char = 0;

printf("What is your age? ");
scanf("%i", &age);

/** 
 * This code will completely skip over the prompt.
 * If you insert getchar(); *twice* before the next scanf() statement,
 * then it will work as expected as the 'dangling' <enter key> characters
 * will be discarded and scanf will be forced to look for new input.
 */
printf("Press any key: ");
scanf("%c", &my_char);

printf("You entered: %c which is the number %u\n", my_char, my_char);


Common Mistake

Your code is executed sequentially so do not try to assign variables before asking for input:

int weight_lb = 0;
int weight_kg = weight_lb * 1.6; // <-- Assigning this too early!

printf("What is your weight in lb? ");
scanf("%i", &weight_lb);

printf("Your weight in kg: %i\n", weight_kg);



Assignment

You should setup Hercules to make sure you can provide input to the board correctly :

  • To provide input to your Board from your computer's PC, you need to open Hercules Program at 38400bps by going to the Serial Tab.
  • Right click on the serial window and make sure "CR/LF" and "Local Echo" are checked.
  • To enter input, you can simply type on the Hercules window and hit the <Enter key> to enter text from your keyboard, which will be transmitted to the Board.
  • Also note that after you open the COM Port in Hercules, the reset button should be pressed on the Board to restart the program otherwise you might miss the output if you open the COM port too late.

Note for future labs :
Normally, your future labs will build on previous labs. In case you want to preserve your old code, just rename the old main() function to something earlier such as lab3 and write a new main function. Note that there can only be ONE main() function per program.


We will improve the percentage calculator by allowing a user to input values for us:

  1. Declare the following float variables :
    • Maximum exam score, user's exam score, and percentage.
  2. Ask the user to input data into your variables, such as:
    • "What is the max score of your exam: "
    • "What was your score: "
  3. Calculate the percentage and print it out with output similar to:
    • "You got 45/50 and your percentage is: 90.0%"
  4. Display "Program finished, press any key to quit ..."
    Test to be sure that the program quits only when a user presses a key.
    Print out the key user pressed: "You pressed Q to quit the program"


Questions

  • After completing the assignment, try removing & symbol for one of the scanf statements.
    What is the program output? Does it work as expected?