On this page

Files and String Streams

Every program so far took its input from the keyboard and sent its output to the output panel. When the program ended, all of it was gone. A file is text that is kept under a name, such as scores.txt, and is still there after the program has ended. This lesson reads files and writes them.

Very little of it is new. std::cin is a stream: a source that hands over one value after another. A file is opened as a stream too, and >> and std::getline work on it as they do on std::cin. The last two sections make a stream out of a line of text, and convert between text and numbers.

Reading from a file

To read a file, a program declares a variable of type std::ifstream, an "input file stream", and gives it the file's name. The type comes from the header <fstream>.

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream file("shelf.txt");
    std::string title;
    int copies = 0;
    int total = 0;
    while (file >> title >> copies) {
        std::cout << title << ": " << copies << "\n";
        total += copies;
    }
    std::cout << "Books: " << total << "\n";
}
Atlas 3
Novel 12 Poems
5
Atlas: 3
Novel: 12
Poems: 5
Books: 20

std::ifstream file("shelf.txt"); reads: the type std::ifstream, the name file, and in parentheses the name of the file to open. The variable could have any name. From this line on, file is a stream that hands over what shelf.txt holds, starting with its first character.

Everything else is module 3 and module 5 with file in the place of std::cin.

  • file >> title >> copies reads a word and then a whole number. >> skips spaces and line ends alike, so it does not matter that Poems and its 5 are on different lines of the file.
  • The read stands in the test of the while. It is true each time both values were read, and false when the file has no more to give. The loop therefore ends at the end of the file, as a loop on std::cin ends when the input runs out.

Three things are different from the keyboard.

  • Nothing is typed. The program does not wait for anybody: the text is in the file already.
  • The file is named in the program, without a folder. In the lab, a task's files lie beside the program and are shown under the editor.
  • Reading does not change the file. A second std::ifstream opened on shelf.txt, in this program or in the next one, starts at Atlas again.

<fstream> is a header like the others. A program that uses std::ifstream must include it.

The file that is not there

The program above trusts that shelf.txt exists. Now suppose the name is misspelt.

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream file("shelv.txt");
    if (!file) {
        std::cout << "Cannot open shelv.txt\n";
        return 0;
    }
    std::string title;
    int copies = 0;
    int total = 0;
    while (file >> title >> copies) {
        total += copies;
    }
    std::cout << "Books: " << total << "\n";
}
Atlas 3
Novel 12 Poems
5
Cannot open shelv.txt

There is no file named shelv.txt, so it cannot be opened. That is not a compile error: the compiler knows nothing about the files a program will find when it runs. It does not stop the program either. The stream file is created all the same, in a failed state, and from then on every read from it fails at once and stores nothing.

Without the if, this program would run to the end and print Books: 0. The loop's test would be false the first time, and total would still hold the 0 it started with. A reader of that output cannot tell a missing file from a shelf with no books on it. So the rule is: test the stream straight after opening it, before reading anything.

Module 4 used a read as a condition: if (std::cin >> x). A stream on its own can be a condition too. It counts as true while the stream is usable, and as false once something has failed. ! is the "not" of module 4, so if (!file) reads "if the file is not usable".

Inside the if, the program says what went wrong and leaves with return 0;. A return in main ends the program, as a return ends any function. Outside the lab, many programs return 1 at such a place, to tell whatever started them that something went wrong. This course returns 0 everywhere.

A file's name is a string, so it does not have to be written into the program. It can be read from the input.

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::string name;
    std::cin >> name;
    std::ifstream file(name);
    if (!file) {
        std::cout << "Cannot open " << name << "\n";
        return 0;
    }
    int value = 0;
    int largest = 0;
    while (file >> value) {
        if (value > largest) {
            largest = value;
        }
    }
    std::cout << "Largest in " << name << ": " << largest << "\n";
}
14 62 37
depths.txt
Largest in depths.txt: 62

This program works for any file of numbers that are not negative, and it reports a name it cannot open in place of an answer that looks real.

A file that opens may still be empty. Then the stream is usable, the first read fails because there is nothing to read, and the loop body never runs. Opening and reading are tested separately.

A file, line by line

>> reads word by word and forgets where the lines ended. When the lines matter, read them with std::getline. Its first value is the stream to read from, which until now was always std::cin.

#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream file("settings.txt");
    if (!file) {
        std::cout << "Cannot open settings.txt\n";
        return 0;
    }
    std::string line;
    int kept = 0;
    int skipped = 0;
    while (std::getline(file, line)) {
        if (line.size() == 0 || line[0] == '#') {
            ++skipped;
        } else {
            std::cout << line << "\n";
            ++kept;
        }
    }
    std::cout << kept << " settings, " << skipped << " other lines\n";
}
# colours
ink dark blue
paper cream

# sizes
margin 24
ink dark blue
paper cream
margin 24
3 settings, 3 other lines

while (std::getline(file, line)) is the loop of module 9. Each turn reads one whole line into line, spaces included, and removes the line end from the stream without storing it. The test is false when there are no more lines.

This program treats a line that starts with # as a note and does not print it. Notice the order of the two tests joined by ||. An empty line has no character at position 0, so line.size() == 0 is asked first. When it is true the answer is already known, and line[0] is never looked at.

Three facts about lines.

  • An empty line in the file is a line. getline reads it as an empty string, and the loop takes a turn for it. The file above has six lines.
  • The last line counts whether or not a line end follows it.
  • getline after >> on the same stream has the trouble of module 3: the line end that >> left behind is read as an empty line. Reading a file either with >> only or with getline only avoids it.

A std::string variable holds one line at a time. To keep them all, push_back each line onto a std::vector<std::string>, as module 9 did with lines from the keyboard.

Writing a file

The type for writing is std::ofstream, an "output file stream", from the same header. Everything << can send to std::cout it can send to an std::ofstream.

#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>

int main() {
    std::ofstream out("label.txt");
    if (!out) {
        std::cout << "Cannot write label.txt\n";
        return 0;
    }
    out << "To: Oslo\n";
    out << std::setw(6) << 2300 << " grams\n";
    out.close();

    std::ifstream back("label.txt");
    std::string line;
    int lines = 0;
    while (std::getline(back, line)) {
        ++lines;
    }
    std::cout << "label.txt has " << lines << " lines\n";
}
To: Turin
450 grams
fragile
keep dry
label.txt has 2 lines
To: Oslo
  2300 grams

Before the program ran, label.txt held four lines about a parcel for Turin. Afterwards it holds two lines about Oslo, and nothing else.

Opening a file for writing empties it. The four old lines are gone at the line std::ofstream out("label.txt");, before anything new is written. What the program then sends with << is the whole of the new file. If no file of that name exists, opening creates one.

Nothing appears in the output panel for out << .... The text goes to the file and only there. "\n" ends a line in a file as it does on the screen, and std::setw, std::fixed and std::setprecision work as they do with std::cout.

Opening for writing can fail as well, for example when the name is not one a file may have. The test is the same if (!out).

out.close(); finishes the file. An output stream does not hand every character to the file the moment << runs. It collects text and passes it on in larger pieces, and the last piece is passed on when the stream is closed. A program that writes a file and then reads it back must close it first, or it may read a file that is not complete yet.

A stream is also closed when its variable ends, at the closing brace of the block or function it was declared in. A function that opens a stream, writes, and returns has therefore closed the file, and at the end of main every file is closed. close() is needed only when the same function goes on to use the file again, as here.

In the lab, every file a program writes is shown with its output. Every Run starts with the task's own files again. A file written by one Run is not there for the next, and a file your program emptied is back as it was.

One function for the keyboard and for a file

A function that reads numbers and adds them up should not care where the numbers come from. Streams make that possible, because a stream can be a parameter.

#include <fstream>
#include <iostream>

double total_of(std::istream& in) {
    double total = 0;
    double amount = 0;
    while (in >> amount) {
        total += amount;
    }
    return total;
}

void print_receipt(std::ostream& out, double total) {
    out << "Total due: " << total << "\n";
}

int main() {
    double typed = total_of(std::cin);

    std::ifstream till("till.txt");
    if (!till) {
        std::cout << "Cannot open till.txt\n";
        return 0;
    }
    double from_file = total_of(till);

    print_receipt(std::cout, typed + from_file);
    std::ofstream receipt("receipt.txt");
    print_receipt(receipt, typed + from_file);
}
10
3.25
2.5 4
Total due: 19.75
Total due: 19.75

std::istream is the type of "any stream that can be read from". std::cin is one. An std::ifstream is one as well: it is an std::istream that happens to get its characters from a file. So total_of accepts both, and inside it in >> amount does not know which it has been given.

std::ostream is the same idea for writing. std::cout is an std::ostream, and so is an std::ofstream. print_receipt is called twice with the same total. The first call writes the line on the screen, the second writes it into receipt.txt. Both types come with <iostream>.

The & is not a choice. A stream parameter is always a reference, for two reasons.

  • A stream cannot be copied. double total_of(std::istream in), without the &, asks for a copy, and the compiler rejects every call of it.
  • A copy would be of no use anyway. Reading moves the stream forward, and the caller needs its own stream to have moved. After total_of(till) has returned, till is at the end of its file, and a second total_of(till) would return 0.

It is a plain reference and not a const one, for the same reason: reading from a stream changes it, and so does writing to one.

By custom the stream is the first parameter. Notice also what total_of does not do. It does not open a file and it does not test whether one opened. The function that has the name of the file does that, here main, and a function that is handed a stream trusts that it is usable.

Taking a line apart

>> cannot say where a line ended, and getline hands over a whole line in one piece. Often a program needs both: read one line, and then read the values inside it. An std::istringstream, an "input string stream", is a stream that gets its characters from a string. Its header is <sstream>.

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::ifstream file("routes.txt");
    if (!file) {
        std::cout << "Cannot open routes.txt\n";
        return 0;
    }
    std::string line;
    while (std::getline(file, line)) {
        std::istringstream parts(line);
        int route = 0;
        parts >> route;
        std::string stop;
        std::string last = "nowhere";
        int stops = 0;
        while (parts >> stop) {
            last = stop;
            ++stops;
        }
        std::cout << "Route " << route << ": " << stops << " stops, ends at " << last << "\n";
    }
}
12 Harbour Market Station
7 Station Hilltop
40 Market Museum Park Harbour Depot
Route 12: 3 stops, ends at Station
Route 7: 2 stops, ends at Hilltop
Route 40: 5 stops, ends at Depot

std::istringstream parts(line); makes a stream named parts that holds a copy of the text of line. Reading from parts with >> works like reading from std::cin or from a file. The difference is where it ends: parts runs out at the end of the one line. The inner while therefore reads the stops of this route and no further, however many there are.

parts is declared inside the outer loop's braces, so every line gets a new stream that starts at its own first character. So do stops and last, which must start afresh for each route.

A string stream also answers the question "does this line hold what I expect?", because a read from it can be tested like any read.

#include <iostream>
#include <sstream>
#include <string>

void show(const std::string& line) {
    std::istringstream parts(line);
    std::string item;
    int amount = 0;
    if (parts >> item >> amount) {
        std::cout << amount << " of " << item << "\n";
    } else {
        std::cout << "skipped [" << line << "]\n";
    }
}

int count_words(std::istream& in) {
    std::string word;
    int words = 0;
    while (in >> word) {
        ++words;
    }
    return words;
}

int main() {
    show("kettle 4");
    show("kettle four");
    show("kettle");
    show("");

    std::istringstream text("one short sentence");
    std::cout << count_words(text) << " words\n";

    std::ostringstream made;
    made << "Total: " << 7 << "\n";
    std::cout << made.str();
}
4 of kettle
skipped [kettle four]
skipped [kettle]
skipped []
3 words
Total: 7

In show, the test parts >> item >> amount is true only when a word and a number were read. four is not a number, the third line has no second value, and the fourth has nothing at all. None of these stops the program. The read fails quietly and the else runs.

An std::istringstream is an std::istream too. count_words takes any input stream, and here it is given text made on the spot. That makes such a function easy to try out: no file is needed, and nothing has to be typed.

The last three lines show the opposite type. An std::ostringstream collects what is sent to it with <<, and made.str() gives everything collected so far as one string. A function that writes to an std::ostream& can be handed one, and what it wrote can then be looked at.

Numbers and text

"12" and 12 are different values of different types. The first is text, two characters long. The second is a number. + joins two strings and adds two numbers, so with std::string a = "12"; and std::string b = "3"; the value of a + b is the text "123".

Two functions from <string> convert between the two.

  • std::stoi(text) gives the int that the text spells. The name is short for "string to int".
  • std::to_string(number) gives the text that spells the number.
#include <iostream>
#include <string>

int main() {
    std::string clock = "07:45";
    std::size_t colon = clock.find(':');
    int hours = std::stoi(clock.substr(0, colon));
    int minutes = std::stoi(clock.substr(colon + 1));
    int since_midnight = hours * 60 + minutes;
    std::cout << since_midnight << "\n";

    std::string label = "Minute " + std::to_string(since_midnight) + " of the day";
    std::cout << label << "\n";
    std::cout << label.size() << "\n";

    std::cout << std::stoi("  42 apples") + 1 << "\n";
}
465
Minute 465 of the day
21
43

find and substr from module 8 cut the text at the colon into "07" and "45". Those are still strings. std::stoi turns them into the numbers 7 and 45, and only then can the program multiply and add.

std::to_string(since_midnight) goes the other way. Its result is the string "465", which + can join to other text. Without it, "Minute " + since_midnight would not mean "put the number into the text". Printing with << never needed this, because << converts numbers itself. std::to_string is for building a string that is kept, returned or measured.

The last line shows how std::stoi reads. It skips spaces at the front, takes digits for as long as it finds them, with a minus sign before them if there is one, and stops at the first character that cannot belong to the number. " apples" is ignored.

What if there is no number at the front at all?

#include <iostream>
#include <string>

int main() {
    std::string word = "apples";
    std::cout << "before\n";
    int n = std::stoi(word);
    std::cout << "after " << n << "\n";
}

This program prints before and then stops. std::stoi has no int to give back for "apples", and no way to say so in its result, so the program is ended at that line. The same happens for an empty string, and for digits that spell a number too large for an int. Part IV of the course shows how a program can catch such a failure and carry on. Until then, call std::stoi only on text that is known to hold a number: because the task promises it, or because the program has looked first.

Looking first is a loop over the characters.

#include <cctype>
#include <iostream>
#include <string>

bool is_whole_number(const std::string& text) {
    int n = text.size();
    if (n == 0 || n > 9) {
        return false;
    }
    for (int i = 0; i < n; ++i) {
        if (!std::isdigit(text[i])) {
            return false;
        }
    }
    return true;
}

int main() {
    std::cout << is_whole_number("465") << "\n";
    std::cout << is_whole_number("4x5") << "\n";
    std::cout << is_whole_number("") << "\n";
    std::cout << is_whole_number("12345678901234") << "\n";
}
1
0
0
0

Text of one to nine digits always fits in an int, so std::stoi is safe on any string this function accepts.

A string stream is the other safe way. parts >> amount on text that is not a number fails quietly, as show in the last section relied on. Use >> when the values are separated by spaces. Use find, substr and std::stoi when they are separated by something else, such as the colon here or the commas of the lab's last task.

std::to_string also accepts a double, and then always gives six digits after the point: std::to_string(2.5) is "2.500000". For text with a chosen number of digits, send the value to an std::ostringstream with std::fixed and std::setprecision.

Your turn

Now try it yourself

Predict what a program will do, run it, and step through it line by line. The checks tell you when your own code works.

Loading the lab…

In this lab

  1. The same >> from a file

    The file numbers.txt holds three numbers on two lines:

    14 9
    27
    

    This program opens the file and reads from it with >>. Nothing is typed at the keyboard. Decide what it prints before you run it.

  2. The file that is not there

    Two files lie beside this program. numbers.txt is the file of the last step:

    14 9
    27
    

    blank.txt holds one empty line and nothing else.

    Read the name in the program letter by letter. Then decide what it prints.

  3. Line by line

    This program prints the first line of notes.txt. The file is shown under the editor.

    Change it to print every line of the file, with the line's number, a colon and a space in front. After the last line, print how many lines there were:

    1: Water the fig tree
    2: Return the library books
    3: Call Odile about Friday
    Lines: 3
    

    An empty line in the file is a line: it is counted, and it is printed as its number and the colon. The checks run your program with other files named notes.txt, one of them with no lines at all.

  4. Write it down

    This program prints the lines of poem.txt in capital letters.

    Change it so that the capital lines go to a second file, loud.txt, and not to the screen. On the screen, print one line only, after the loop: how many lines were written.

    Lines written: 3
    

    loud.txt should then hold:

    SLOW RIVER
    LOW BRIDGE
    ONE HERON WAITING
    

    The lab shows the files a program wrote below its output. poem.txt itself must stay as it is.

  5. Keyboard or file

    sum_all reads whole numbers from the stream it is given until that stream has no more, and returns their total. main calls it twice: with std::cin, and with a file.

    The Input box holds 5 6 7. The file more.txt holds:

    100
    20 3
    
  6. One line, several values

    Each line of results.txt holds a name and then that player's scores. Different players have different numbers of scores, and Juno has none yet.

    The program makes a string stream from each line and prints the name it reads from it. Change it to print, after each name, the total of the scores on that line:

    Mira 20
    Tobi 10
    Ansel 25
    Juno 0
    

    Every line of the file holds a name, which is one word, and then nothing but whole numbers. The checks run your program with other files named results.txt.

  7. Text to number and back

    a and b are strings, although both look like numbers. Each of the four lines of output comes from a different mix of text and numbers. Decide what each prints, and ask yourself what type the value has before it is printed.

  8. Count lines and words

    Write a program that counts the lines and the words of a file.

    The name of the file is read from the input, as one word. The Input box holds story.txt, and that file is shown under the editor. The starter already reads the name.

    If the file opens, print two lines:

    Lines: 4
    Words: 16
    
    • Every line counts, an empty one too.
    • A word is a run of characters with no space in it, so dawn. is one word. Words may have several spaces between them, and a line may begin or end with spaces.

    If the file cannot be opened, print one line and nothing else, with the name that was read:

    Cannot open story.txt
    

    The checks run your program with other files and other names in the input. One of the names belongs to no file.

  9. Load the scores

    A file of scores has one player on each line: a name, which is one word, and a whole-number score. Files typed by people are not tidy. This one has an empty line, a line with no score, and a line whose score is not a number.

    Write, above main:

    std::vector<Entry> load(std::istream& in) reads lines from in until it has no more. For every line that holds a name and a number after it, it adds an Entry with that name and score to a vector. Every other line is skipped, and the reading goes on with the next line. Anything on a line after the score is ignored. It returns the vector, with the entries in the order of the lines.

    load does not open a file and does not print. It reads from the stream it is given. The checks call it with streams of their own, made from text. With another parameter type the checks cannot be built, and you will be told so.

    main is written. With scores.txt it should print:

    Loaded 3
    Noor 91
    Pavel 78
    Cy 85
    
  10. Save the table

    Write a function that writes a table of entries to any output stream, and use it for the screen and for a file.

    void save(std::ostream& out, const std::vector<Entry>& entries) writes one line for each entry to out, in the order of the vector:

    • the name at the left of a column 10 characters wide,
    • then the score at the right of a column 5 characters wide,
    • then a line end.

    For the three entries in main that is:

    Noor         91
    Pavel        78
    Cy           85
    

    No name is longer than 10 characters. For an empty vector save writes nothing.

    main calls save twice with its vector: once with std::cout, and once with an output file stream opened on table.txt. The screen and the file then hold the same three lines.

    The checks call save with an output stream of their own and with other entries. With another parameter type the checks cannot be built, and you will be told so.

  11. A score table

    Write the program this module has been building towards: it loads a score table from a file, sorts it, and saves the ranking in another file.

    The name of the file is read from the input, as one word. The Input box holds scores.txt. Each of its lines is a name, a comma, and a whole-number score. A name may be several words, so the comma is the only place where a line can be cut:

    Noor Haddad,91
    Pavel,78
    Cy Okafor,104
    Bo,9
    

    Your program:

    1. loads the lines into a std::vector<Entry>;
    2. sorts the entries by score, highest first;
    3. writes the ranking to a file named ranked.txt, one line for each entry: its rank, counted from 1, a full stop, a space, the name, a space, the score;
    4. prints the winner on the screen.

    For the file above, ranked.txt holds

    1. Cy Okafor 104
    2. Noor Haddad 91
    3. Pavel 78
    4. Bo 9
    

    and the screen shows

    Winner: Cy Okafor (104)
    

    If the file named in the input cannot be opened, print Cannot open and the name, as in Cannot open scores.txt, and write no file at all.

    You may rely on this: a file that opens has at least one line, every line has exactly one comma with a whole number from 0 to 100000 after it, and no two scores are equal.

    std::sort cannot sort this vector as it stands, because there is no < for two Entrys. Sort it with the selection sort of module 11: compare the score members, and exchange whole entries. The checks run your program with other files and other names.

  12. Sum the columns

    table.txt holds rows of whole numbers. Every row has the same count of numbers, but your program is not told that count, nor the number of rows.

    Print the sum of each column, on one line, with a space between the sums. For the file shown:

    27 17 23
    

    table.txt is always there when your program runs, and it has at least one row. Numbers may be negative.

    The checks run your program with tables of other shapes.

  13. Comma-separated

    Many files separate the values on a line with commas. A value between two commas is called a field, and a field may be empty: the second line of orders.txt has nothing between its two commas.

    Write, above main:

    std::vector<std::string> split_commas(const std::string& line) returns the fields of line, in order. The commas themselves belong to no field. Spaces are ordinary characters and stay in their field.

    • split_commas("lamp,2,35") has the three elements lamp, 2 and 35.
    • split_commas("desk mat,,18") has three elements: desk mat, an empty string, and 18.
    • split_commas("a,") has two elements: a and an empty string.
    • A line with no comma has one field, the whole line. That holds for an empty line as well: split_commas("") has one element, an empty string.

    So the vector always has one element more than the line has commas.

    main is written. It prints the total of the third field of every line of orders.txt:

    Total: 57
    

    The file's lines all have at least three fields, and the third is a whole number.

  14. The longest line

    Write a program that finds the longest line of a file.

    The name of the file is read from the input, as one word. The Input box holds speech.txt.

    Print the number of the longest line, counted from 1, and the line itself, in this form:

    Line 3: Nobody believes a speaker who says that.
    

    The longest line is the one with the most characters, spaces included. When several lines share the greatest length, print the first of them.

    Two cases have no longest line. Each has its own message, with the name that was read:

    • The file cannot be opened: Cannot open speech.txt
    • The file opens but has no lines at all: speech.txt is empty

    A file with lines in it is not empty, even when every one of its lines is.

  15. Number the lines

    Write a program that copies draft.txt into a new file, numbered.txt, with a line number in front of every line.

    Each line of numbered.txt is: the line's number, at the right of a column 3 characters wide, then a colon, a space, and the line as it was. For the file shown, numbered.txt holds:

      1: Dear Odile,
      2:
      3: the boat leaves at nine.
      4: Bring a coat.
    

    Empty lines are copied and numbered like the others. The program prints nothing on the screen. draft.txt is always there when your program runs.

    draft.txt itself stays as it is. The checks use drafts of other lengths, one with more than nine lines.

  16. A report from any stream

    Write two functions above main. One builds a sentence about a score table as a string. The other writes that sentence to any output stream.

    std::string summary(const std::vector<Entry>& entries) returns one string, with no line end, that says how many entries there are and which has the highest score:

    • for the three entries in main: 3 entries, best Noor (91)
    • for exactly one entry: 1 entry, best Noor (91), with entry and not entries
    • for an empty vector: 0 entries, and nothing more

    When several entries share the highest score, the first of them is named. summary prints nothing. Build the string with + and std::to_string.

    void report(std::ostream& out, const std::vector<Entry>& entries) writes the summary and a line end to out.

    main is written. It sends the report to the screen and to report.txt. The checks call both functions with vectors and streams of their own.

  17. A to-do file

    Write a program that keeps a list of tasks in a file.

    1. Load the lines of tasks.txt into a std::vector<std::string>. If the file cannot be opened, carry on with an empty vector: a list that does not exist yet is an empty list.
    2. Read one new task from the keyboard, as a whole line, and add it to the vector.
    3. Write every task back to tasks.txt, one on each line.
    4. Print how many tasks the file now holds.

    Put the loading and the saving in two functions of your own. Make sure the stream you read from is closed before you open the same file for writing: a stream declared inside a function is closed when the function returns.

    Nothing checks this one. When you have finished, go through the list below.