Overview
FILE STREAM I/O
Data file streams can be used as an alternative to the standard i/o. To use the file commands, the ofstream/ifstream or fstream headers must be included:
ofstream.h output file
ifstream.h input file
fstream.h input & output file.
ofstream MyFile;
MyFile is a variable of type ofstream (i.e. an output file)
MyFile.open("a:\\test.cpp".ios::app);
opens the file text.cpp to add text to the end of the file.
THE IOS COMMANDS
Repeat after me - there are no commands in C++
The ios commands are
in open for reading
out open for writing
ate seek end of file
app append mode - add to end of file
trunc truncate if file exists
nocreate open fails if file does not exist
noreplace open fails if file exists
binary binary mode (default mode is text)
MyFile.put('q');
Put the character 'q' into the file.
MyFile.close();
Closes the file down.
cerr
The cerr stream is used to receive error messages. cerr is the standard error stream, corresponding to stderr in the ANSI C library. By default, cerr is assigned to the screen, but it can be redirected.
Rubbish! cerr is sent to the standard output stream. That can be to just about anywhere!
cerr <<"Run out of memory.\n";
The output from the above will probably go to the screen.
EXERCISE 21
Define a class with only one public variable - an integer. Define a 20 element array of this type. Use a pointer to point at this array. Each time a key is pressed store this character into the array. When the array goes out of scope (i.e. at the end of the file) the keystokes are to be written to a file.
EXERCISE 22
Write a second program to read this file and display the original sequence of keystrokes.
Strings can be stored to files in the same way as any other data type would be written to a file:
#include <iostream.h>
#include <fstream.h>
void main(void)
{
const int length = 80;
char name[length];
char *sptr = name; // sptr has the address of start of name
// string.
ofstream MyFile;
cout << "Type a line of text\n";
cin.getline(name,length,'\n');
MyFile.open("a:\\stringy.cpp",ios::app);
while (*sptr != '\0')
{
Myfile.put(*sptr++);
}
MyFile.close();
}
Where to start? Not a good idea using a char * for the sptr - a far better method would be to use std::string - the data is being placed on the stack with a good risk of damaging existing data. Next up, no sort of checking to see if the file was opened, then the hardwire to a file on a disc - it is MS specific - not many OSes use a:. Finally, the usual batch of errors on headers and namespaces
PROJECT FILES
So far we have written, compiled and linked one program at a time. The program might have had serveral functions in it, but for the purposes of compilation they were all treated as a single entity. However, it is possible to break a program into separate files, each consisting of one or more functions. These programs can be compiled separately and linked together to form the final executable program.
There now follows a series of separate files. There is only one file with a main function within it.
prjmain.cpp
#include <iostream.h>
#include <conio.h>
/* both of these statements could be in the header file */
#include "a:\cpp\prjhead.h"
/* header file is used to list all the function prototypes in external
functions to make this file neater */
void main()
{
clrscr();
cout << "in prjmain.cpp\n" << endl;
FuncOne();
FuncTwo();
}
Hardwires and incorrect headers. The comment under the #includes is also incorrect
All the functions that are not written in pjrmain.cpp need prototypes defining. They can be defined in prjmain.cpp. However, it is neater to define them all in a header file and include the header file..
pjrhead.h
extern void FuncOne(); extern void FuncTwo();
Notice in the following two small code files that header files still need to be included. This is needed for compilation.
prjone.cpp
#include <iostream.h>
void FuncOne()
{
cout << "in prjone.cpp " << endl;
}
prjtwo.cpp
#include <iostream.h>
void FuncTwo()
{
cout << "in prjtwo.cpp" << endl;
}
All these files are bound together using a project file.
This little lot has absolutely nothing to do with C++
HOW TO SET UP A PROJECT FILE
- From the project menu select open project. Since this is your first project file, type the name of your choice (the prj extension will be added automatically). Notice that the project file will be saved to the suggested directory - you may want to select a different drive / directory.
- The project window then opens. You need to list all the files that you will want to link together.
- Select insert. Insert the files and then press done. Notice that any header files written do not need to be included - these are identified from with the code files.
- Each one of the source code files can now be edited and compiled separately.
- To produce the final executable file, compile make is selected. This will compile all the source code files that are out of date (i.e. changed since their last compile) and then link all the compiled object files together.
- The compile build all is the same as the make utitity, but will compile and link regardless of whether they are out of date.
EXERCISE 23 - THE TELEPHONE BOOK
Define a class with two variables. One a string (to hold a person's name), the other an 11 digit phone number. These must be stored on disc in an ASCII text file called phone.dat.
The member functions of the class should include:
- add a phone number
- access phone number by name
- access name by phone number
- display name and phone number
- print names and numbers
The phone database is created by reading the names from disc into an array in memory.
The whole exercise should be setup as a project using three separate modules:
- header file containing the class declaration
- function file containing the function declarations
- main file containing the program execution.
The telephone number must be verified that it is a number.
Drop the .h and these are fine (accepting that "file" does not have to mean data being stored to some form of magnetic or optical media