Basics of Formatted Input/Output
Concepts
- I/O is essentially done one character (or byte) at a time
- stream -- a sequence of characters flowing from one place to
another
- input stream: data flows from input device (keyboard, file,
etc) into memory
- output stream: data flows from memory to output device
(monitor, file, printer, etc)
- Standard I/O streams (with built-in meaning)
- stdin: standard input stream (default is keyboard)
- stdout: standard output stream (defaults to monitor)
- stderr: standard error stream
- stdio.h -- contains basic I/O functions
- scanf: reads from standard input (stdin)
- printf: writes to standard output (stdout)
- There are other functions similar to printf
and scanf that write to and read from other streams
- Formatted I/O -- refers to the conversion of data to and from a
stream of characters, for printing (or reading) in plain text format
- All text I/O we do is considered formatted I/O
- The other option is reading/writing direct binary information
(common with file I/O, for example)
Output with printf
Recap
- The basic format of a printf function call is:
printf (format_string, list_of_expressions);
where:
- format_string is the layout of what's being printed
- list_of_expressions is a comma-separated list of variables or
expressions yielding results to be inserted into the output
- We've already seen output of string literals, and output involving
integers
int numStates = 50;
printf("Hello, world!\n");
printf("There are %d states in the U.S.\n", numStates );
Conversion Specifiers
A conversion specifier is a symbol that is used as a placeholder in a
formatting string. For integer output, %d is the specifier that
holds the place for integers.
Here are some commonly used conversion specifiers (not a comprehensive
list):
%d int (signed decimal integer)
%u unsigned decimal integer
%f floating point values (fixed notation) - float, double
%e floating point values (exponential notation)
%s string
%c character
A more comprehensive list is found in Deitel, Chapter 9
Printing Integers
- To output an integer, use %d in the format string, and an
integer expression in the list_of_expressions.
int numStudents = 35123;
printf("FSU has %d students", numStudents);
// Output:
// FSU has 35123 students
- We can specify the field wicth (i.e. how many 'spaces' the item prints
in). Defaults to right-justification. Place a number between the
% and the d. In this example, field width is 10:
printf("FSU has %10d students", numStudents);
// Output:
// FSU has 35123 students
- To left justify, use a negative number in the field width:
printf("FSU has %-10d students", numStudents);
// Output:
// FSU has 35123 students
- If the field width is too small or left unspecified, it defaults to
the minimum number of characters required to print the item:
printf("FSU has %2d students", numStudents);
// Output:
// FSU has 35123 students
- Specifying the field width is most useful when printing multiple lines
of output that are meant to line up in a table format
Printing Floating-point numbers
- Use the %f modifer to print floating point values in fixed
notation:
double cost = 123.45;
printf("Your total is $%f today\n", cost);
// Output:
// Your total is $123.450000 today
- Use %e for exponential notation:
printf("Your total is $%e today\n", cost);
// Output:
// Your total is $1.234500e+02 today
Note that the e+02 means "times 10 to the 2nd power"
- You can also control the decimal precision, which is the number of
places after the decimal. Output will round to the appropriate number of
decimal places, if necessary:
printf("Your total is $%.2f today\n", cost);
// Output:
// Your total is $123.45 today
- Field width can also be controlled, as with integers:
printf("Your total is $%9.2f today\n", cost);
// Output:
// Your total is $ 123.45 today
In the conversion specifier, the number before the decimal is field
width, and the number after is the precision. (In this example, 9 and 2).
- %-9.2 would left-justify in a field width of 9, as with
integers
Printing characters and strings
- Use the formatting specifier %c for characters. Default
field size is 1 character:
char letter = 'Q';
printf("%c%c%c\n", '*', letter, '*');
// Output is: *Q*
- Use %s for printing strings. Field widths work just like
with integers:
printf("%s%10s%-10sEND\n", "Hello", "Alice", "Bob");
// Output:
// Hello AliceBob END
output.c -- contains all of
the above sample outputs. Try running it yourself
scanf
Basics
- To read data in from standard input (keyboard), we call the
scanf function. The basic form of a call to scanf is:
scanf(format_string, list_of_variable_addresses);
- The format string is like that of printf
- But instead of expressions, we need space to store incoming data,
hence the list of variable addresses
- If x is a variable, then the expression
&x means "address of x"
- scanf example:
int month, day;
printf("Please enter your birth month, followed by the day: ");
scanf("%d %d", &month, &day);
- Conversion Specifiers
- Mostly the same as for output. Some small differences
- Use %f for type float, but use %lf for
types double and long double
- A more comprehensive list found in Deitel, pg 379
- The data type read, the conversion specifier, and the variable used
need to match in type
- White space is skipped by default in consecutive numeric reads.
But it is not skipped for character/string inputs.
Example
input1.c -- linked here
#include <stdio.h>
int main()
{
int i;
float f;
char c;
printf("Enter an integer and a float, then Y or N\n> ");
scanf("%d%f%c", &i, &f, &c);
printf("You entered:\n");
printf("i = %d, f = %f, c = %c\n", i, f, c);
}
Sample run #1
User input underlined, to distinguish it from program output
Enter an integer and a float, then Y or N
> 34 45.6Y
You entered:
i = 34, f = 45.600, c = Y
Sample Run #2
Enter an integer and a float, then Y or N
> 12 34.5678 N
You entered:
i = 12, f = 34.568, c =
Note that in this sample run, the character that was read was NOT
the letter 'N'. It was the space. (Remember, white space not skipped on
character reads).
This can be accounted for. Consider if the scanf line looked like
this:
scanf("%d%f %c", &i, &f, &c);
There's a space betwen the %f and the %c in the format
string. This allows the user to type a space. Suppose this is the typed
input:
12 34.5678 N
Then the character variable c will now contain the 'N'.
input2.c -- a version of the
example with this change is linked here
Interactive Input
You can make input more interactive by prompting the user more carefully.
This can be tedious in some places, but in many occasions, it makes
programs more user-friendly. Example:
int age;
double gpa;
char answer;
printf("Please enter your age: ");
scanf("%d", &age);
printf("Please enter your gpa: ");
scanf("%lf", %gpa);
printf("Do you like pie (Y/N)? ");
scanf("%c", %answer);
A good way to learn more about scanf is to try various inputs
in various combinations, and type in test cases -- see what happens!