e<fstream>library comes with many functions to help test to see if things are working. One example is thefail()function. We use this function to determine whether the file was opened successfully or not. We usually useifstatements with the function so that if the file does not open correctly we can warn the user. For example: i n F i l e . open (” T e x t F i l e . t x t ”) ; i f ( i n F i l e . f a i l ( ) ) { c o u t << ” F a i l e d t o open ! ”; }
is will warn the user if the file did not open correctly. If the filedidopen correctly, the program would continue without printing the error message.
e next function is theeof()(endof file) function. is function tests to see if the stream has reached the end of the file. is function is very useful in order to know when to stop reading from the file. For example:
i n t number ; i n F i l e . open (” T e x t F i l e . t x t ”) ; w h i l e ( ! i n F i l e . e o f ( ) ) { i n F i l e >> number }
is example shows how theeof()function can be used in awhileloop. ewhileloop will read integers from the file until the program reaches the end of the file. is is useful for gathering all the data from one file.
eget()andput()functions are used to read and write single characters, respectively. e functionget()allows the program to read in a single character into a variable of typechar. When we use the>>operator, spaces, tabs and new- lines—the whitespace characters—around data are skipped automatically. However withget(), nothing is done automatically, so the whitespace characters can be extracted, too. e member functionget()takes one argument in parentheses that must be acharvariable. For example:
c h a r C h a r a c t e r ; i f s t r e a m i n F i l e ; c i n . g e t ( C h a r a c t e r ) ;
/ / or
is will read in the next character typed on the keyboard or from the file. Even if the next character is a space, tab, or newline, the program will store that character in the variable.
eput()function is used to output one character. is function takes one argument of typecharin the parentheses. For example:
c h a r C h a r a c t e r = ’ \ n ’; / / n e w l i n e c h a r a c t e r o f s t r e a m o u t F i l e ; c o u t . put ( C h a r a c t e r ) ; / / or o u t F i l e . put ( C h a r a c t e r ) ;
18.8 Review estions
1. What do we call the type of object used to control data flowing into your program?
2. What do we call the type of object used to control data flowing out of your program?
3. What header file must you#includein order to useifstreamand
ofstream?
4. What areifstreamandofstreamused for?
5. How do you declare anifstream object namedinputand an of- streamobject namedoutput?
6. How would you open a file namedTextFile.txtwith anifstream
object calledinput?
7. How would you close a file namedTextFile.txtwith anofstream
object calledoutput?
8. What kind of function is theeof()function and what does it do? 9. What are the benefits of using files for input and output?
10. What is the difference betweencin >> c;andcin.get(c);ifcis of typechar?
11. Write a program that outputs the contents of some file to the screen. 12. Write a program that reads in a text file and prints to the screen the number
18.9 Review Answers
1. An input stream 2. An output stream
3. You need to#include <fstream>
4. ifstreamis used to read data from a file. ofstreamis used to write data to a file.
5. ifstream input; ofstream output;
6. input.open("TextFile.txt");
7. output.close();
8. eeof()function is a member function. It returnstrueif the program has reached the end of the file.
9. File input and output are useful because files provide a way to store data permanently. With keyboard input and screen output, the data is temporary and disappears once the program is finished. e data stored in files on the other hand remains the same until another program changes it. Also, an input file can be used by many programs at the same time without having to store multiple copies or re-enter the data over and over again.
10. e firstcinstatement the next non-whitespace character intoc, but the call tocin.get()stores the next character incwhether it is whitespace or not.
18.10 Further Reading
• http://www.cprogramming.com/tutorial/lesson10.html • http://www.cplusplus.com/doc/tutorial/files/
Chapter 19
Pointers
Pointers do just what they sound like they do. ey point to a space in memory, usually a location occupied by a variable. A pointer is an address in memory. e pointer itself is a variable, but it also refers to a variable. It is declared using an asterisk following the data type:
i n t * p t r ;
e variable namedptris of typeint*, an “integer pointer” that stores the address of a variable of typeint.
To indicate that a pointer variable is not pointing toward any usable data, we oen set its value toNULL, which is defined as zero when you#include <cstdlib>:
i n t * p t r = NULL ;
C++11 provides a dedicated null pointer object callednullptrthat can be used similarly:
i n t * p t r = n u l l p t r ;
ere are two operators used in conjunction with pointers. e*operator, beyond being used for multiplication and for pointer declarations, also acts as the
dereference operator. e dereference operator changes the pointer into the value it is pointing to. It “follows” the address stored in the pointer and returns whatever is in that location.
e&operator is thereference operator. e dereference operator returns the memory address of the variable it precedes. You will use this to produce a pointer
Figure 19.1: e state of the variables aer lines 1-3
to the indicated variable. Let’s declare pointerpand use it:
i n t * p ; / / D e c l a r e an i n t p o i n t e r
i n t v a r 1 = 2 ; / / D e c l a r e an i n t , s e t i t t o 2
p = &v a r 1 ; / / Take t h e a d d r e s s o f v a r 1 and s t o r e i t i n p
c o u t << * p ; / / Go t o t h e a d d r e s s s t o r e d i n p ; / / r e t u r n t h e v a l u e ; p r i n t i t out
e output of this code is:
2
Here is a slightly longer example:
i n t * p ;
i n t v a r 1 = 2 ;
i n t v a r 2 = 4 ;
p = &v a r 1 ; / / Take t h e a d d r e s s o f v a r 1 and s t o r e i t i n p
* p = v a r 2 ; / / Go t o t h e a d d r e s s s t o r e d i n p ; / / a s s i g n i t t h e v a l u e s t o r e d i n v a r 2 / / The p r e c e d i n g two l i n e s a r e e q u i v a l e n t t o v a r 1 = v a r 2 c o u t << * p << e n d l ; c o u t << v a r 1 << e n d l ; c o u t << v a r 2 << e n d l ; e output of this code is:
4 4 4
Figure 19.1 shows the state of the variables in the second example aer they are declared and initialized (lines 1-3). Aer the fourth line is executed,pwill store the address ofvar1. Figure 19.2 shows the state of the variables. Aer the fih line of code is executed, the location whereppoints is assigned the value stored in
Figure 19.2: e state of the variables aer line 4
Figure 19.3: e state of the variables aer line 5
19.3 shows the state of the variables.
Use caution when declaring pointers. If you are declaring more than one pointer in a single line, make sure to indicate each pointer variable with the*before the variable name. Here is a correct declaration of two pointers:
i n t * p , * q ;
is results in an integer pointer namedpand an integer pointer namedq. Contrast that with the below code:
i n t * p , q ;
alent way to write the above is:
i n t q , * p ;
19.1 Review estions
1. What is the output of the following code?
i n t * a , b , c ; a = &b ; b = 5 ; c = 1 ; b = b − b ; c = b * b ; * a = c − * a ; a = &c ; * a = c − 7 ; c = c + c ; * a = * a + b ; c = c + b ; b = c − 3 ; c = * a − 7 ; c o u t << * a << e n d l ; c o u t << b << e n d l ; c o u t << c << e n d l ;
2. What is the output of the following code? i n t a , b , * c ; a = 7 ; b = 4 ; c = &a ; a = * c − a ; * c = * c + 4 ; a = b + a ; c = &b ; a = a − b ; * c = b + a ; * c = * c − 1 ; a = a * 1 ; a = b − * c ; a = a − * c ; c o u t << a << e n d l ; c o u t << b << e n d l ; c o u t << * c << e n d l ;
19.2 Review Answers
1. -21 -17 -21 2. -7 7 7Chapter 20
Dynamic Data
Up to this point, we have only discussed variables that are set up at compile time. Allocating space for variables at compile time is adequate in many cases, but occa- sionally a program will need to allocate space for data in memory while it is running. Consider the following code:
i n t a r r a y S i z e ;
c o u t << ” E n t e r t h e number o f e l e m e n t s i n your a r r a y : ”; c i n >> a r r a y S i z e ;
/ / We want t o c r e a t e an a r r a y with a r r a y S i z e e l e m e n t s
i n t myArray [ a r r a y S i z e ] ; / / SYNTAX ERROR !
In order to allocate the space formyArray, the compiler needs to know how many elements make up the array so that there is enough room in memory to ac- commodate the array. Unfortunately, the value ofarraySizeis not known until the user enters something on the keyboardaer the program has started runningand as a result, the compiler returns a syntax error.
In C++, pointers are used to keep track of dynamically-allocated data:
f l o a t * f P t r = NULL ; / / ( 1 ) D e c l a r e a p o i n t e r t o a f l o a t , / / which c u r r e n t l y p o i n t s nowhere
In order to dynamically allocate an object of typefloat, we use thenew
operator:
f P t r = new f l o a t; / / ( 2 )
e created object of typefloatdoes not have a name, so thenewoperator
NULL
float*
fPtr
float*
fPtr
float
float*
fPtr
2.2float
(1) (2) (3)Figure 20.1: Allocation and dereferencing of pointers
returns afloat*that can be used to access the object. is pointer is stored in
fPtr. We use the dereference operator (*, that is) to access the data:
* f P t r = 2 . 2 ; / / ( 3 ) Goes t o a d d r e s s a t f P t r & p u t s 2 . 2 t h e r e
c o u t << ” Data a t ” << f P t r << ” : ” << * f P t r << e n d l ;
/ / T h i s o u t p u t s : Data a t 0 x 2 0 0 1 0 2 b 0 : 2 . 2 / / Note t h a t t h e a d d r e s s l i s t e d may d i f f e r
/ / Also n o t e t h e d i f f e r e n c e between p r i n t i n g f P t r and * f P t r
Notice that when a value is assigned tofPtr, the pointer is being changed. When a value is assigned to*fPtr(notice the dereference operator), the floating- point value at the address stored infPtris changed.
float*
fPtr
2.2float
(4)float
Memory leakfloat*
fPtr
2.2float
(5) 3.3float
Memory leakFigure 20.2: Allocation and memory leaks
f l o a t * f P t r ; f P t r = new f l o a t; * f P t r = 2 . 2 ; / / Goes t o a d d r e s s a t f P t r & p u t s 2 . 2 t h e r e c o u t << ” Data a t ” << f P t r << ” : ” << * f P t r << e n d l ; f P t r = new f l o a t; / / ( 4 ) f P t r now h o l d s a d d r e s s o f / / a new f l o a t o b j e c t * f P t r = 3 . 3 ; / / ( 5 ) c o u t << ” Data now a t ” << f P t r << ” : ” << * f P t r << e n d l ; / / T h i s o u t p u t s : / / Data a t 0 x 2 0 0 1 0 2 b 0 : 2 . 2 / / Data now a t 0 x 2 0 0 4 8 3 c 0 : 3 . 3
In this example, thefloatcontaining the value2.2still resides in memory,
but is no longer reachable. is condition is called amemory leak, and results in programs that consume more memory than they require. In order to free up the
memory properly, we use thedeleteoperator: f l o a t * f P t r ; f P t r = new f l o a t; * f P t r = 2 . 2 ; / / ( 6 ) Goes t o t h e a d d r e s s a t f P t r and s t o r e s 2 . 2 t h e r e c o u t << ” Data a t ” << f P t r << ” : ” << * f P t r << e n d l ; d e l e t e f P t r ; / / ( 7 ) F r e e s up t h e d y n a m i c a l l y−a l l o c a t e d / / memory a t t h e a d d r e s s s t o r e d i n f P t r
At this point in the code,fPtrcan be referred to as adangling pointer, since the memory location it refers to is no longer valid, and the pointer just “dangles” there, pointing to nothing useful.
float*
fPtr
2.2float
(6)float*
fPtr
dangling pointer (7)Figure 20.3: Deallocation and dangling pointers
Arrays can be dynamically allocated, too:
f l o a t * f P t r = new f l o a t[ 1 0 ] ; / / A l l o c a t e an a r r a y o f t e n / / f l o a t s and s t o r e t h e i r l o c a t i o n i n f P t r
Arrays must be deleted in a similar fashion, but the syntax changes slightly:
20.1 Review estions
1. Write code to declare an integer pointer and dynamically allocate an integer. On the next line, assign this dynamically-allocated integer the value 13. 2. Given the following code, write a few lines that deallocate any dynamically-
allocated memory and set all pointer values toNULL:
i n t * a = new i n t [ 2 4 ] ; i n t * b ; i n t c ; b = &c ;
20.2 Review Answers
1. * i P t r = 1 3 ;i n t * i P t r = new i n t; 2. d e l e t e [ ] a ; a = NULL ; b = NULL ;20.3 Further Reading
• http://www.cplusplus.com/doc/tutorial/dynamic/Chapter 21
Classes and Abstraction
Imagine for a second you’re behind the wheel of an automobile. You’re driving