Previous: 2.3 Testing the Program
Up: 2 Basic Concepts
Next: 2.5 More C Statements
Previous Page: 2.3.2 Documenting the Code

2.4 Input: Reading Data

To address the deficiency in our program mentioned above, the next task is to write a program that reads data typed by the user at the keyboard, calculates pay, and prints out the data and the results. In this case, the program must communicate with the user to get the input data.

Task

PAY1: Same as PAY0, except that the data values id_number, hours_worked, and rate_of_pay should be read in from the keyboard.

The algorithm is the same as before except that the data is read rather than set:

print title of program;
     read the data for id_number, hours_worked, and rate_of_pay;
     set pay to the product of hours worked and rate of pay;
     print the data and the results;
In the implementation of the above algorithm, we must read in data from the keyboard. In a C program, all communication with a user is performed by functions available in the standard library. We have already used printf() to write on the screen. Similarly, a function, scanf(), is available to read data in from the keyboard and store it in some object. Printf() performs the output function and scanf() performs the input function.

The function scanf() must perform several tasks: read data typed at the keyboard, convert the data to its internal form, and store it into an object. In C, there is no way for any function, including scanf(), to directly access a variable by its name defined in another function. Recall that we said the scope of a variable was the block in which it was defined, and it is only within this scope that a variable name is recognized. But if scanf() cannot directly access a variable in main(), it cannot assign a value to that variable. So how does scanf() store data into an object? A function can use the address of an object to indirectly access that object.

Therefore, scanf() must be supplied with the address of an object in which a data value is to be stored. In C, the address of operator, &, can be used to obtain the address of an object. For example, the expression &x evaluates to the address of the variable x. To read the id number from the keyboard and store the value into id_number, hours_worked and rate_of_pay we use the statements:

scanf("%d", &id_number);
     scanf("%f", &hours_worked);
     scanf("%f", &rate_of_pay);
The first argument of scanf() is a format string as it was for printf(). The conversion specification, %d, specifies that the input is in decimal integer form. Scanf() reads the input, converts it to an internal form, and stores it into an integer object whose address is given by the next unmatched argument. In this case, the value read is stored into the object whose address is &id_number, i.e. the value is stored into id_number. The remaining two scanf statements work similarly, except the conversion specification is %f, to indicate that a floating point number is to be read, converted to internal form and stored in the objects whose addresses are &hours_worked and &rate_of_pay respectively. The type of the object must match the conversion specification, i.e. an integer value must be stored into an int type object and a floating point value into a float object.

To better understand how scanf() works, let us look in a little more detail. As a user types characters at the keyboard they are placed in a block of memory called a buffer (most but not all systems buffer their input). The function scanf() does not have access to this buffer until it is complete which is indicated when the user types the newline character, i.e. the RETURN key. (see Figure 2.6).

The function scanf() then begins reading the characters in the buffer one at a time. When scanf() reads numeric input, it first skips over any leading white space and then reads a sequence of characters that make up a number of the specified type. For example, integers may only have a sign () and the digits 0 to 9. A floating point number may possibly have a decimal point and the or E exponent indicators. The function stops reading the input characters when it encounters a character that does not belong to the data type. For example, in Figure 2.6, the first scanf() stops reading when it sees the space character after the 3. The data is then converted to an internal form and stored into the object address specified in the argument. Any subsequent scanf() performed will begin reading where the last left off in the buffer, in this case at the space. When the newline character has been read, scanf() waits until the user types another buffer of data.

At this point we can modify our program by placing the scanf() statements in the code replacing the assignments to those variables. However, when we compile and execute the new program, nothing happens; no output is generated and the program just waits. The user does not know when a program is waiting for input unless the program prompts the user to type in the desired items. We use printf() statements to print a message to the screen telling the user what to do.

printf("Type ID Number: ");
     scanf("%d", &id_number);
     printf("Hours Worked: ");
     scanf("%f", &hours_worked);
     printf("Hourly Rate: ");
     scanf("%f", &rate_of_pay);
The prompts are not necessary to read the data, without them, scanf() will read what is typed; but the user will not know when to enter the required data. We can now incorporate these statements into a program that implements the above algorithm shown as the file pay1.c in Figure 2.7.

When the program is run, here is the sample output:

Everything the user types at the keyboard is also echoed to the screen, and is shown here in slanted characters.

We have now seen two ways of storing data into objects: assignment to an object and reading into an object. Assignment stores the value of an expression into an object. Reading into an object involves reading data from the input, converting it to an internal form, and storing it in an object at a specified address.

The function scanf() can read several items of data at a time just as printf() can print several items of data at a time. For example,

scanf("%d %f %f", &id_number, &hours_worked, &rate_of_pay);
would read an integer and store it in id_number, read a float and store it in , and read a float and store it in rate_of_pay. Of course, the prompt should tell the user to type the three items in the order expected by .



Previous: 2.3 Testing the Program
Up: 2 Basic Concepts
Next: 2.5 More C Statements
Previous Page: 2.3.2 Documenting the Code

tep@wiliki.eng.hawaii.edu
Tue Aug 16 14:01:55 HST 1994