19
1 ©1992-2012 by Pearson Education, Inc. & John Wiley & Sons Some portions are adopted from C++ for Everyone by Horstmann ENGR 1200U Introduction to Programming Lecture 14 Working with Data Files (Chapter 5) Dr. Eyhab Al-Masri ENGR 1200U Winter 2013 - UOIT Loops are often required for reading data from the keyboard or from a data file There are three common loop forms 1. Counter-Controlled Loop 2. Sentinel-Controlled Loop 3. End-Of-Data Loop

Lec14.pdf

Embed Size (px)

DESCRIPTION

Lec 14

Citation preview

Page 1: Lec14.pdf

1

©1992-2012 by Pearson Education, Inc. & John Wiley & SonsSome portions are adopted from C++ for Everyone by Horstmann

ENGR 1200U Introduction to Programming

Lecture 14Working with Data Files (Chapter 5)

Dr. Eyhab Al-Masri

ENGR 1200UWinter 2013 - UOIT

Loops are often required for reading data from the keyboard or from a data file

There are three common loop forms1. Counter-Controlled Loop

2. Sentinel-Controlled Loop

3. End-Of-Data Loop

Page 2: Lec14.pdf

2

ENGR 1200UWinter 2013 - UOIT

Used for reading input data if the number of data values is known before the data are entered

Number of data values is storedin a counter

counter is often used to controlthe number of iterations

can be easily implemented usingthe while or for loops

ENGR 1200UWinter 2013 - UOIT

Used for reading input data if a special data value exists that can be used to indicate the end of the dataWhen reading a sequence ofinputs, you often need a methodto indicate end of the sequence

A value that serves as a signalfor termination is called asentinel

Page 3: Lec14.pdf

3

ENGR 1200UWinter 2013 - UOIT

Assume we would like compute the average of a set of salary values. We will use -1 as a sentinel.◦ Inside the loop, we read an input. If the input is not -1,

we process it. To compute the average, we need the total sum of all salaries, and the number of inputs.

while (...){

cin >> salary;if (salary != -1){

sum = sum + salary;count++;

}}

while (salary != -1){

cin >> salary;if (salary != -1){

sum = sum + salary;count++;

}}

ENGR 1200UWinter 2013 - UOIT

There is one problem: when the loop is entered the first time, no data value have been read. ◦ Hence, no initial value for salary

double salary = 0;while (salary != -1){

cin >> salary;if (salary != -1){

sum = sum + salary;count++;

}}

do{

cin >> salary;if (salary != -1){

sum = sum + salary;count++;

}} while (salary != -1);

Page 4: Lec14.pdf

4

ENGR 1200UWinter 2013 - UOIT

Is the most flexible loop for reading input data It is structured to continue

executing the statements insidethe loop while new data areavailableNo prior knowledge of datavalues is required

No sentinel value is required

©1992-2012 by Pearson Education, Inc. & John Wiley & SonsSome portions are adopted from C++ for Everyone by Horstmann

(Chapter 5)

Page 5: Lec14.pdf

5

ENGR 1200UWinter 2013 - UOIT

Develop problem solutions in C++ that: Open and close data files for input and output. Read data from files using common looping

structures. Check the state of an input stream. Recover from input stream errors.

ENGR 1200UWinter 2013 - UOIT

Page 6: Lec14.pdf

6

ENGR 1200UWinter 2013 - UOIT

C++ input/output library is based on the concept of streams

C++ defines the cin and cout objectsto represent the standard input (keyboard) and standard output (console).◦ An input stream is a source of data◦ An output stream is a destination for data

C++ also defines the standard error stream, cerr

ENGR 1200UWinter 2013 - UOIT

The most common sources and destinations for data are the files on your hard disk.

Standard C++ library also defines special kinds of streams for file input and output.

◦ #include <ifstream>◦ #include <ofstream>

Page 7: Lec14.pdf

7

ENGR 1200UWinter 2013 - UOIT

ENGR 1200UWinter 2013 - UOIT

This is a stream of characters. It could be from the keyboard or from a file. Each of these is just a character - even these: 3 -23.73 which, when input, can be converted to: ints or doublesor whatever type you like.(that was a '\n' at the end of the last line)&*@&^#!%#$ (No, that was –not- a curse!!!!!!!!!!¥1,0000,0000 (price of a cup of coffee in Tokyo)Notice that all of this text is very plain - Nobold or green of italics – just characters – andwhitespace (TABs, NEWLINES and, of course... theother one you can’t see: the space character:(another '\n')(&& another) (more whitespace) and FINALLY:

Aren't you x-STREAM-ly glad this animation is over?

newline characters

And there were no sound effects!!!

Page 8: Lec14.pdf

8

ENGR 1200UWinter 2013 - UOIT

The stream you just saw in action is a plain text file. No formatting, no colors, no video or music

The program can read these sorts of plain text streams of characters from the keyboard, as has been done so far.

ENGR 1200UWinter 2013 - UOIT

To read or write disk files, you use variables

ifstream for input from plain text files

ofstream for output from plain text files

fstream for input and output from binary files

Page 9: Lec14.pdf

9

ENGR 1200UWinter 2013 - UOIT

To read from a file stream, you need to open the stream (the same applies for writing)◦ Opening a stream simply associates your stream

variable with the disk file

Or just

ifstream sensor1;sensor1.open(“sensor1.dat”);

ifstream sensor1(“sensor1.dat”);

ENGR 1200UWinter 2013 - UOIT

File names can contain directory path information:

UNIXin_file.open("~/newfiles/input.dat");

Windowsin_file.open("c:\\newfiles\input.dat");

?When specifying file name as string literal and the namecontains backslash characters (i.e. Windows path andfilename), you must supply each backslash twice to avoidhaving escape characters in the string

Page 10: Lec14.pdf

10

ENGR 1200UWinter 2013 - UOIT

String object (or class) has the c_str method to convert the C++ string to a C string

Open method only accepts C strings

Example:

cout << "Please enter the file name: ";string filename;cin >> filename;ifstream in_file;in_file.open(filename.c_str());

Open method passed the C string version of the filename the user typed

ENGR 1200UWinter 2013 - UOIT

Failure to open file If opening the named file fails, the fail

error bit is set, and all statements to read from the file will be ignored.

◦ NO error message will be generated but the program will continue to execute.

◦ Check to be sure that the open was successful. fail() method of istream returns false.

Page 11: Lec14.pdf

11

ENGR 1200UWinter 2013 - UOIT

ifstream sensor1;

sensor1.open("sensor1.dat");

if ( sensor1.fail() ) //open failed

{

cerr << "File sensor1.dat could not be opened";

exit(1); //end execution of the program

}

Example

ENGR 1200UWinter 2013 - UOIT

Summary of Steps Required

1. Create input stream variable

2. Open the file

3. Check for failure to open

4. Read from file

Page 12: Lec14.pdf

12

ENGR 1200UWinter 2013 - UOIT

To write to a file stream, you need to open the stream ◦ Opening a stream simply associates your stream

variable with the disk file

Or just

ofstream sensor1;sensor1.open(“balloon.dat”);

ofstream sensor1(“balloon.dat”);

ENGR 1200UWinter 2013 - UOIT

By default, opening a file for output in this way will either create the file if it doesn’t already exist or overwrite a previously existing file.

If you wish to simply append new content to the previously existing file, you may open the file in append mode:

sensor1.open(“balloon.dat”, ios::append);

Page 13: Lec14.pdf

13

ENGR 1200UWinter 2013 - UOIT

The close() method for both inputand output stream objects should be called when the program is done with the file.

◦ The method will be called automatically when the program exits.

◦ Manually closing a stream is necessary only if you would like to open the file again in the same program run

ENGR 1200UWinter 2013 - UOIT

Page 14: Lec14.pdf

14

ENGR 1200UWinter 2013 - UOIT

To read a file, some knowledge about the contents of the file are needed:

Three common structures:

1. Name of the file2. Order and data types of the values stored in the file

the file

1. First-line in file contains the number of lines/records

in the file

2. Trailer signal/sentinel signal used to indicate the last

line/record in the file

3. End-of-file used directly to indicate last line/record in

the file

ENGR 1200UWinter 2013 - UOIT

sensor1.dat

10

0.0 132.5

0.1 147.2

0.2 148.3

0.3 157.3

0.4 163.2

0.5 158.2

0.6 169.3

0.7 148.2

0.8 137.6

//open input file

ifstream sensor1(“sensor1.dat”);

//read the number of data entries

int numEntries;

sensor1 >> numEntries;

//read every row

double t, y;

for (int i = 0; i < numEntries; i++)

{sensor1 >> t >> y;//do something with the data

}

//open input file

ifstream sensor1(“sensor1.dat”);

//read the number of data entries

int numEntries;

sensor1 >> numEntries;

//read every row

double t, y;

for (int i = 0; i < numEntries; i++)

{sensor1 >> t >> y;//do something with the data

}

Page 15: Lec14.pdf

15

ENGR 1200UWinter 2013 - UOIT

sensor2.dat

0.0 132.5

0.1 147.2

0.2 148.3

0.3 157.3

0.4 163.2

0.5 158.2

0.6 169.3

0.7 148.2

0.8 137.6-99 -99

//open input fileifstream sensor2(“sensor2.dat”);//read every rowdouble t, y;do{

sensor1 >> t >> y;if (t < 0 || y < 0)

break;//do something with data

} while (! sensor1.eof());

//open input fileifstream sensor2(“sensor2.dat”);//read every rowdouble t, y;do{

sensor1 >> t >> y;if (t < 0 || y < 0)

break;//do something with data

} while (! sensor1.eof());

ENGR 1200UWinter 2013 - UOIT

sensor3.dat

0.0 132.5

0.1 147.2

0.2 148.3

0.3 157.3

0.4 163.2

0.5 158.2

0.6 169.3

0.7 148.2

0.8 137.6

//open input fileifstream sensor3(“sensor3.dat”);//read every rowdouble t, y;while (! sensor3.eof()) {

sensor1 >> t >> y;if (sensor3.fail())

break;//do something with the data

}

//open input fileifstream sensor3(“sensor3.dat”);//read every rowdouble t, y;while (! sensor3.eof()) {

sensor1 >> t >> y;if (sensor3.fail())

break;//do something with the data

}

Page 16: Lec14.pdf

16

ENGR 1200UWinter 2013 - UOIT

ENGR 1200UWinter 2013 - UOIT

After opening an output file, writing toa file is no different from writing to standard output.

Must decide on a file format.◦ Sentinels can be hard to choose to avoid conflict with

valid data.◦ Knowing in advance how many lines/records are in

the file is sometimes difficult or impractical.◦ Usually best to use eof-style file format where file

structure contains only valid information.

Page 17: Lec14.pdf

17

ENGR 1200UWinter 2013 - UOIT

In addition to indicating if an erroroccurs when opening a file, fail() may also be used to detect other types of errors.

◦ Errors can occur when trying to read from an input stream when the data on the input stream isn’t of the appropriate type.

ENGR 1200UWinter 2013 - UOIT

Whitespace is defined as blank, tab, newline, form feed, and carriage return characters.

Used to separate data when reading from an input stream.

For example, to read 2 integers from an input stream, there must be whitespace between the two numbers.◦ C++ ignores the whitespace to read the numbers.◦ If any other characters are encountered, the error

(fail) state is set.

Page 18: Lec14.pdf

18

ENGR 1200UWinter 2013 - UOIT

Do not generate notification of errors!◦ Only set the error state.

Reads will not affect the state of the input buffer or alter variables.◦ However the program will continue executing!

Must “clear” the error state before additional input may be read (using istream’s clear() method).

ENGR 1200UWinter 2013 - UOIT

Every stream has an associated state Indicated by a set of state flags:◦ badbit, failbit, eofbit, goodbit.

Events may alter the stream state:Event badbit failbit eofbit goodbitInitialization of a stream 0 0 0 1

Failure to open a file 0 1 0 0

Unexpected data encountered

0 1 0 0

End of file encountered 0 1 1 0

Page 19: Lec14.pdf

19

ENGR 1200UWinter 2013 - UOIT

Method Description

bool bad() Returns true if badbit is set.bool eof() Returns true if eofbit is set.bool fail() Returns true if failbit is set.bool good() Returns true if goodbit is set.void clear(iostate flag = goodbit)

Sets the state flags.

iostate rdstate() Returns the value of the state flags.