05 - Inputs (scanf)
User Input
The next command to learn in the C Programming Language is that which allows you to sense a user input and store that information in a variable. It looks like this:
Example:
scanf("%d",&variable);
Explanation of each part:
scanf is the command to get a user input.
"%d" looks for an integer as the input.
& tells the computer that the next thing written is the location/variable where you will store this information.
variable is the name of the variable where you will store this input.
A few additional notes about taking in user input with the "scanf" function are:
There is an automatic new line (\n) created after the "scanf" function finishes reading (see the example below and notice the extra new line that was created). If you put a "\n" inside the scanf, it will not work as you expect (more on this at the bottom in common mistakes).
Unless taking in a single character "char", white spaces are not read by "scanf". Instead the "scanf" function reads white space as ending the first input and getting ready for the second input. This can cause a lot of havoc in your code if you are not careful. This will be discussed in more depth in the section below titled "Multiple Placeholders".
For more information about the "scanf" function, check out this link: Link.
Activity 1
Edit the code above to take in a character and store it in a variable called my_own_char.
On another line, print "The character you entered is <char>"
Solution: Link
Activity 2
Ask the user for 3 integers, storing these each in a separate variable.
On another line, print the three numbers.
On another line, print the sum of the three numbers in a complete sentence
On another line, print the product of the three numbers in a complete sentence
Solution: Link
Multiple Placeholders
Instead of using many separate lines of code, you can use many placeholders in the same line. An example commands are below:
Example #1: (Link)
// Create the variables first
int num1, num2;
// Print instructions
printf("Please enter two integers, separated by a space: ");
// Takes in something like "3 -12"
// Separates it by spaces and stores it as two integers
scanf("%d%d", &num1, &num2);
//Uses each variable separately
printf("\nThe numbers entered were %d and %d\n", num1, num2);
Example #2: (Link)
// Create the variables first
int user_number;
char user_char1, user_char2;
// Print instructions
printf("Please enter an integer and a character in that order without any space between them: ");
// Since the second thing being scanned for is a single character,
// it will scan white space as a character - in other words, user_char1 will be the space " "
// Scanning for anyhting but a character will skip whitespace and use white space as separating inputs
scanf("%d%c%c", &user_number, &user_char1, &user_char2);
//Uses each variable separately
printf("\nThe integer was %d. The first character was \'%c\'. The second character was \'%c\' \n", user_number, user_char1, user_char2);
Below is a working example of this in action. You will notice that the final example search for three characters does not seem to work. The explanation is below in the "Frequently Asked Questions" section.
Activity 3
Edit the code above to ask the user for a three letter word.
Store each letter of the word as a separate variable (examples: first_letter, second_letter and third_letter)
Print a single line that states back the three separate letters such as, "The first letter you entered was c. The second letter you entered was a. The third letter you entered was r."
Solution: Link
Activity 4
Ask the user to input three numbers of any data type you choose in a single line, separated by spaces.
Store these numbers in three different variables.
Calculate the average of the three numbers.
Print the three numbers and their average in a single complete sentences using a single "printf" command.
Example:
Comp: Enter three doubles separated by spaces
User: 1.5 2.2 3.1
Comp: The average of 1.500000, 2.200000 and 3.100000 is 2.266667
Solution: Link
Frequently Asked Questions
Question - So why does the scanf function seem to work with integers and decimals but not with characters?
Answer - Whitespace (spaces and new-line characters '\n') count as characters but are ignored by numerical data types. Integers and Decimals can be easily distinguished from whitespace, and hence whitespace is ignored and used only as separations between inputs. The program above will work with your numbers even if you put 1,000 spaces in between them and keep hitting the "Enter" key over and over and over. The scanf function continues to run until it eats another integer or decimal - whichever it is waiting for. There are two reasons this is more difficult when scanning for characters:
When you finish scanning for numbers, the scanf function eats the last number you entered but leaves the "Enter" key that you pressed (the '\n' character) in the input buffer. If the next thing you scan for is a number, no problem. The '\n' in the input buffer is ignored. However, if the next thing you scan for is a character, then the '\n' is saved as the value of that first character. This is listed as a common mistake below and there are at least five possible fixes given
Whitespace is read as characters. So even if you responded to the prompt "Please enter three characters separated by spaces" correctly and entered "a b c", it would save the first three characters of this which are 'a', ' ', 'b'. Notice that is counted the space as a character. Notice also that you now have three characters still in the input buffer (space, c, new-line).
Fix for this: In between your characters that you desire, you can ignore the whitespace and read until you get a non-whitespace character. Add %*[ \n\t] in between your three character placeholders, so %c%c%c becomes %c%*[ \n\t]%c%*[ \n\t]%c. The asterisk means "do not save this" and the brackets mean "keep reading anything with these characters in it". So it keeps reading all of the spaces, new-lines and tabs until it encounters something different. Similar to this, but much simpler is to place spaces in between your %c which says to ignore white space. Fixed Example Link
Common Mistakes
Forgetting the '&' before the variable when scanning - When scanning for primitive data types, you need a "&" before the variable name. "&variable" points to the memory location whereas "variable" refers to the value of the variable. Try out these examples, where I purposefully left out the ampersand - Example #1 (character) - Example #2 (integer). Note that this mistake is not an issue when referring to objects such as a string. When scanning for a string, the "&" is unnecessary. We will explore the "why" behind this as we get into object-oriented programming.
Putting a '\n' inside the scanf function - If you want to scan an integer and accidentally include a new-line (\n) inside the function like this scanf("%d\n",&int1); instead of scanf("%d",&int1); then your program will seem to be unending. No matter how many times you hit enter, it won't go past the "scanf" line. What happened is that you said to scan for two things. The first thing, %d, says to look for an integer. The second direction, \n, tells it to read any amount of white space, including your new-lines. You have to type in any non-white space character to make it stop. Try it out - Example.
Scanning for a character after a a scanf for a different type of data and having the the character be skipped - This is because scanning for a character (%c) does not ignore white space. When you scan for other data types, it uses white space as denoting the separation between entries. When scanf takes in another data type such as an integer, it leaves the "enter" key you hit in the input buffer as a new-line character or '\n'. If you scan for a data type other than a character (%c) this new-line character is ignored, however if you scan for a single character this new-line character is taken in as the input before you have a chance to enter anything. There are a few fixes for this. Either: (1) scan for " %c" with a space before the %c, as this denotes to skip all white space. (2) Scan for "%c%c" and throw away the first character by saving it as some temporary variable. (3) Scan for "%*c%c" where the %*c means "don't save the first character you encounter". (4) When ending a scanf line, you can include %*c after your final placeholder to eat/delete a single character after the last thing that scanf had sucked up - which should be the new-line character (unless they added other stuff). (5) Just as entering a space will direct the scanf function to skip whitespace, you can explicitly tell it which symbols to skip using %*[ \n\t]. This literally says, to read all of the spaces, new-lines and tabs and the asterisk says to just delete/not-save them. So you should put this before your %c to ignore all white space. - Link to Repl.it Example