Comp202 Transitions in Programming:C++
Online lecture while the instructor is at a conference
Summary:
This online "lecture" will cover file handling in c++ and the object
oriented/system independant approach to file handling used in the Qt
libraries. Please select whatever method makes the most sense to you
when doing your project.
Next week we'll look at another feature of c++ which Java does quite differently: the callback function.
Basic C++ file handling:
The c++ standard library provides three classes for reading and writing
files. Note that for this 'lecture' I'll only worry about text files. I
don't want to get into endian issues or other binary file issues.
- ofstream
- for writing to a file only
- fstream
- for file read/writes
- ifstream
- reading from a file only
All three classes wrap an object oriented framework around the c-style
system calls. Each has their own header file, but fstream includes the
other two so often tutorials will skip inclusion of ifstream and
ofstream.
ofstream extends ostream, the class for the std::cout object. (and
ifstream extends and class which extends ... istream, the class of cin).
ofstream has a constructor with default paremeters. (There is one
constructor with default values filled in for the parameters so if you
don't pass parameters, some will be filled in for you.)
The constructor can take now parameters - in which case it doesn't open
any file or it could take a char* in which case it opens the file named
by the char*.
There are also other very commonly used methods
- open which needs to be passed a char* for a file name if you
didn't open it in the constructor. It will open the file for writing
- note that there is technically a second parameter to this method, but I think you should go with the default value.
- close, which takes no parameters and asks the operating system to release the resources for this file now.
- eof() returns true if the file pointer is at the end of the file (there is no more to read) and returns false otherwise.
once you have the file opened, you can write to it.
For example using this I can write:
#include <fstream>
using namespace std;
int main(){
ofstream file;
file.open("demo.txt");
file<< "what shall we do?"<<endl;
for (int i = 0; i<9; i++)
file << i << std::endl;
file.close();
}
Which produces the following output in the file called demo.txt
what shall we do?
0
1
2
3
4
5
6
7
8
If you want to read from a file it is a little more complex. One easy
way to get the data is to use the overloaded streaming operator
>>. This operator will bring in one line of data and put it into
your string variable, then you need to concatinate it together.
The program listing below shows the use of this.
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
int main(){
ifstream file;
string data;
string line;
file.open("demo.txt");
while (!file.eof()){
file>>line;
data+=line;
}
cout << data <<endl;
file.close();
}
The program was run on the file demo.txt created by the program above to give the following output.
whatshallwedo?0123456788
You could maintain the line structure of the original by concatinating
a line break on to the data string between each line concatination.
Using Qt classes to read and write files
Qt has several classes to read and write files as well. I'll introduce 2 of them.
QFile
QFile is much like the java file class. It encapsulates a file on a filesystem. It has several interesting methods
- QFile(QString&)
- a QString is compatable with a string constant
- creates a file object for the string
- exists
- returns true if the file is already on the file system, false otherwise.
- open(flags)
- opens the file in the mode specifed by flags
- IO_ReadOnly opens the file for reading only.
- IO_WriteOnly opens the file for writing only.
- IO_ReadWrite opens the file for both reading and writing.
- IO_Append opens the file for appending.
- these flags can be combined by using binary or eg:
- IO_WriteOnly|IO_Append
- to write at the end of an existing file.
- atEnd
- returns true if eof. false otherwise.
- Q_LONG readLine ( QString & s, Q_ULONG maxlen )
- send a QString reference s, and it will be filled with the next
line of data. The return value is the amount of data put into s. You
can specify a maximum line size if you wish through maxlen
- there is also a version that takes a character pointer rather
than a QString reference as a place to store the data read in from the
line.
QTextStream
QTextStream is a thread safe class for doing reading and writing of
text - in our case to and from files. I'll introduce the methods I
think will be most useful for you and then add references at the end.
QTextStream has lots of constructors, but I think the most useful is
the one that takes a File object (technically the parent class of
QFiles) as a parameter and will act as a stream on that file
there is an atEnd method in the QTextStream that works just like the file version
Once you have the stream opened, just use the streaming operators
>> to get data from the file to a variable and << to write
back to the file. Be sure to call close on the original file when you
are done.
References:
You might find my references useful. I prepared this by reading the Qt Documentation and some of the tutorials
ofstream api documentation
ifstream api documentation.
Tutorial for file reading
QFile API reference page
QText Stream API Reference Page