Built-In Types and Standard Strings in I/O
The iostream library handles input and output for built-in types, standard strings, and programmer-defined types.
When the Values Are Your Own
Most of the input and output you have seen so far moves simple values: whole numbers, decimal numbers, single characters, and text held in standard strings. Those values already have a meaning the library understands. Printing the number 42 or reading a word into a standard string requires nothing special from you, because the library already knows how to handle those kinds of values.
This raises a question the section is built around. What happens when the thing you want to read or write is a value of a type you designed yourself? A program that tracks a list of people, orders, or measurements will often build its own types to represent those records. It would be inconvenient if those records could never be printed or read. The section's answer is that they can, because the iostream library lets programmers define input and output for their own types.
Three Kinds of Values in the Stream
It helps to think of the library as covering three kinds of values. The first is the built-in types, such as numbers and characters. The second is the standard string. The third is the programmer's own types. The source treats the first two as the starting point and then extends the same idea to the third.
| Kind of value | Examples named in the source | Who knows how it is read and written |
|---|---|---|
| Built-in types | Whole numbers, decimal numbers, single characters | The library already knows how |
| Standard strings | Text held in a standard string | The library already knows how |
| Programmer-defined types | A record such as the telephone book Entry | The programmer must supply the rules |
The first two kinds are handled by the library's built-in knowledge. The third kind depends on definitions the programmer writes.
The important point is that the library is not fixed to a predefined list of types. A type you write can take part in input and output as well. The stream interface is the same shape for all three kinds of value; what differs is where the knowledge of the value's layout comes from.
The Telephone Book Entry as a Running Example
To make the idea concrete, the source introduces a simple type named Entry. Its purpose is to represent one entry in a telephone book. The source uses this type as the example for defining input and output on a programmer-defined type, so it is the thread to follow through the rest of this topic.
Notice why a type like Entry is a natural candidate. A single telephone book entry is a bundle of related information about one person. No built-in type describes that bundle as a whole, so a programmer creates a type to represent it. Once that type exists, it is reasonable to want to print an entry to the screen or read one in from a file. That desire is exactly what the iostream extension is meant to support.
Tracing one Entry on its way to the screen
A program holds one telephone book Entry and wants to print it. What has to happen before the record appears as characters?
- 1Start with the record
The program holds one Entry, which bundles related information about one person. The library has no built-in idea of what an Entry looks like.
- 2Apply the programmer's rules
The record is turned into characters that a person or a file can display. For an Entry, the programmer supplies these rules, because the library cannot know the record's parts.
- 3Hand the characters to the stream
The resulting characters pass through the iostream library, which provides the stream machinery for output.
- 4Reach the destination
The characters arrive at the output destination, such as the screen or a file.
The library supplies the stream machinery, while the programmer supplies the knowledge of how an Entry becomes characters.
Why the Library Needs the Programmer's Help
Picture a telephone book entry moving between your program and the outside world. When it is printed, the program turns the record into characters that a person or a file can display. When it is read, characters coming from an input source must be turned back into the record's parts. For built-in types the library already knows how to do this conversion. For an Entry, the programmer has to supply the rules, because the library has no built-in knowledge of what an Entry looks like.
What do you think happens?
Suppose you have a telephone book Entry type but you have written no input or output definition for it. Can the iostream library still print an Entry directly?
Reveal answer
No, the library cannot know the layout of a programmer-defined type, so an input and output definition has to be written for it.
The source states that a user-defined type needs its own input and output definition because the library cannot know its layout.
Mistakes Beginners Make With Custom Types
Common mistake Assuming that any type can be printed because the built-in types can be
Why it failsBuilt-in types and standard strings already have meaning the library understands. A programmer-defined type does not, because the library cannot know its layout.
Do this insteadRecognize that a custom type needs its own input and output definition before it can take part in stream operations.
Common mistake Treating a record like Entry as if it were a single value of a built-in type
Why it failsAn Entry is a bundle of related information about one person. No built-in type describes that bundle as a whole.
Do this insteadThink of the record as several parts that must be turned into characters on output and rebuilt from characters on input.
Common mistake Thinking the library itself knows how to convert a programmer's record into characters
Why it failsThe source says that for an Entry the programmer has to supply the rules.
Do this insteadKeep the division clear: the library provides the stream machinery, and the programmer provides the knowledge of the custom type.
What This Section Leaves for Later
The title of this section names two topics: handling I/O errors and handling end-of-file. Reading a record from a stream can go wrong. The input may be missing, malformed, or may run out before the record is complete. Those situations are what the title refers to.
The connection is still worth keeping in mind. Reading a custom record is the situation where a failed or incomplete read matters most, because a single Entry usually depends on several pieces of input arriving together. Understanding how a custom type is read is therefore the groundwork for understanding how a read can fail.
Tracing a Custom Record
Without writing any code, explain in your own words what must be true before a telephone book Entry can be printed to a file, and name the part of the system that supplies each piece of that knowledge.
Hints
- Start by asking whether the library already knows the layout of an Entry.
- Separate the work done by the library's stream machinery from the work done by the rules the programmer supplies.
- Remember that the source describes output as turning the record into characters a person or file can display.
Key Takeaways
- The iostream library handles built-in types, standard strings, and programmer-defined types, so it is not limited to a fixed list of types.
- A programmer-defined type such as the telephone book Entry needs its own input and output definition because the library cannot know its layout.
- For output, the programmer's rules turn the record into characters; for input, the rules turn characters back into the record's parts, while the library supplies the stream machinery.
- This section introduces user-defined type I/O but leaves error handling and end-of-file handling to be studied from the surrounding course material.