Previous Lecture lect08 Next Lecture

lect08, Tue 02/05

Intro to Makefiles and File I/O

Midterm FAQs:

A feedback form will be released soon! Let us know of any suggestions and concerns for the course.

Lecture Material:

Makefiles:

Makefile Syntax:

  target: dependencies
           command

For example:

  main: main.cpp
         g++ -std=c++11 -o main main.cpp

Note: There is a single tab space at the start of the command line. It must be a tab, not 5 spaces in a row, otherwise, you will have the following error in your makefile: Makefile:2: *** missing separator. Stop.!

Update: We posted an expanded Makefile Walkthrough on Piazza https://piazza.com/class/jqm50idtsek4wz?cid=177

File Input/Output:

  1. When you are done reading from the file, always close your filestream!
    • inStream.close()
    • If you forget, sometimes your processor will handle it and close it for you, but don’t count on this, since it won’t happen if the program exits with an error.
    • Leaving a filestream open leaves you at risk of corrupting that file’s data * Other input filestream functions:
    • getline(inFile, nextLine): Gets the next line from the input file and stores it in the string variable nextLine.
      • Note: The variable string nextLine must have already been declared before using it with getline. It can have any name- nextLine is simply an example.
      • getline() always expects a string as the second parameter. If you want to take in variables besides strings, you will have to convert the input from a string into another format. * Note: When you are reading from an input file, you can only go through the lines forward. If you want to go back and look at previous lines, you will have to close the stream, reopen it, and re-iterate to the line you want. There is no way of moving backwards while in the stream.
    • .fail(): Returns true if the previous filestream operation failed
      • For example, if the following two lines are executed and isFail is true afterwards, then the text file was not successfully opened:
        inFile.open("MyFile.txt");
        bool isFail = inFile.fail();
        
      • An ifstream object may fail to open a file if the file does not exist
    • .good(): Basically the opposite of .fail(). Returns true if the previous filestream operation was a success.
    • .eof(): Checks if you are at the end of a file, returns true if you are.

How can you iterate through every line of a file? * Use a while loop!

     while(!inFile.eof()){
     //loops while not at end of file    
     }

Update: A student posted a good example, which pointed at the fact that using eof() as part of the loop condition is not a good idea! See the example below:

// filestream.cpp
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main()
{
    ifstream ins;
    string nextline;
    string filename = "animals03.txt";

    ins.open(filename);
    if (ins.fail())
    {
        cerr << "Unable to open the file " << filename << endl;
        return -1;
    }

    while (!ins.eof()) {
        ins >> nextline;
        cout << nextline << endl;
    }
    ins.close();

    return 0;
}

Contents of animals03.txt shown via the cat command:

$ cat animals03.txt
duck
duck
goose

Compiling and running the program on the provided file, results in the last line being output twice:

$ g++ filestream.cpp -o filestream
$ ./filestream
duck
duck
goose
goose

See further discussion about it in this post https://stackoverflow.com/questions/21647/reading-from-text-file-until-eof-repeats-last-line.