C++ handles basic file I/O using streaming classes, from which instances of a streaming variable are created. There is a similar feature in Delphi - TFileStream.For example we could declare a file streaming variable in Delphi as follows...
var
FileStream : TFileStream;
begin
FileStream.Create('c:\something.txt', fmOpenWrite or fmCreate);
FileStream.write(buffer, count);
FileStream.free;
end;In C++ the same thing would be accomplished using the classes ofstream, ifstream, and fstream.
Ofstream handles output, ifstream handles input and fstream handles input and output. FStream seems similar then to the file variable in Delphi.
var
AFile : file;
amt : integer;
begin
Assignfile(AFile, 'c:\somefile.brg');
Reset(Afile, 1);
Blockwrite(Afile, buffer[1], 200, amt);
....
Blockread(Afile, buffer[300], 12, amt);
....
end;In the above example the untyped file 'AFile' is opened using 'Reset' and is set to one, which means that the 'record size' for writes is one byte. The Blockwrite statement begins writing at 'Buffer[1]' , writes out 200 bytes, and then returns the number of bytes written in 'amt'. Later, aftering 'seeking' a spot in the file more than likely, the same file variable is used to read into the buffer. Reset allows both read and write, similar to the fstream variable in C++. TFileStream also allows either read or write or 'fmOpenReadWrite' which also mimics fstream in C++.
The following is an example of using the ifstream variable in C++ to write out a file.
remember to include the line #include <fstream.h> at the head of the source file...
Let's assume that we have created a character buffer to store the input...
char buffer[1024];
We need to create an instance of the ifstream class...ifstream AFile("c:\somefile.txt");
A line can be read in as follows ...
Afile.getline(buffer, sizeof(buffer));
The destructor for the class closes the file if it is still open or you can explicitly close the file yourself...
Afile.close();
The code above passes a PChar (pointer to a character array) to the constructor of the ifstream class. It is also possible to use the following line to open a file...
ifstream.Afile;
AFile.open("c:\somefile.txt");One thing to watch out for if you are a Delphi programmer is that C++ uses double quotes for literal strings while Delphi uses single quotes.
To write to a file you can create an instance of the ofstream class, and then use the ' << ' operator to send output to the file.
ofstream.Afile("c:\somefile.txt");
AFile << "Write out this line please" << endl;
AFile.close;The 'endl' means write end of line, or a return carriage.
Like TfileStream the streaming classes in C++ have modes that can be used to describe how the file is to be manipulated. These modes are members of the 'ios' class and are specified as in the following example...
ofstream.Afile("c:\somefile.txt", ios::binary);
The default mode (if none is specified) is textfile mode. The other modes are :
ios::app - append to end of file...
ios::ate - seek end of file on opening...
ios::in - open file for input, used with the fstream class...
ios::out - open for output...
ios::trunc - erase and rewrite the file, which is the default...
If more than one of these is used they are seperated by the bar character (which means 'or'), as follows (note that with TFileStream in Delphi these are seperated by the keyword 'or')...
fstream.Afile("c:\somefile.txt", ios::app | ios::out | ios::binary);
An example of reading a file in and then writing it out using a string variable in C++...
#include <fstream>
int main()
{
ifstream readfile("c:\readfile.txt");
ofstream writefile("c:\writefile.txt");
string thetext;
while (getline(readfile, thetext))
{
writefile << thetext << endl;
}
readfile.close();
writefile close();
}This program does nothing but read the file in and write it out again, and if the file was to manipulated this would of course be included in the while loop code. Note that when only one line is included in a while loop (if/then construct, for loop etc) the curly braces are not strictly required and the line could be written as...
while (getline(readfile, thetext)) writefile << thetext << endl;
As well when the file stream variables go out of scope the file stream class automatically closes the file if it has not already been closed, so the two close statements might not be really required either, but I include them here because it seems like good form.
In Delphi records can be rewritten to disk using the Blockwrite function of an instance of an untyped file variable whose default record size has been set to the size of the record in question. One of the tricky parts of writing out records is that internally everything is kept aligned along double word boundaries for the sake of modern CPUs (which run fastest when operating with 32 bits). So a record with a byte, a byte, and an integer which have the one byte bytes aligned along a 4 byte (double word) boundary to increase CPU performance, which means that when you try to write out the record to disk you can wind up writing out crap (and wondering what went wrong) if you fail to keep this in mind. For example we are assuming here that TheRecord exists and we want to write it to disk...
var afile : file; amt : integer;
begin
Assignfile(afile, 'C;\somefile.txt');
Rewrite(afile, sizeof(TheRecord));
Blockwrite(afile, TheRecord, sizeof(TheRecord), amt);As I mentioned, 'sizeof(TheRecord)' might not turn out the way you would expect because of that business with the 4 byte boundaries in internal memory representation of the record. As well, just a tip, when you write out a buffer always refer to 'buffer[0]' in the Blockwrite statement (assuming zero is the beginning of the buffer, since writing from 'buffer' will write out a bunch of crap starting from whatever the address of the buffer pointer is, rather than starting from the address contained in the buffer pointer, which is what you want...
var afile : file; amt : integer; buffer : array[0..79] of char;
begin
Assignfile(afile, 'c:\something.txt');
Rewrite(afile, 1); {set record size to one byte}
Blockwrite(afile, buffer[0], 80, amt);In this example the record size (in the rewrite procedure) was set to one byte. If we set the record size to 80 then we could write Blockwrite(afile, buffer[0], 1, amt); and write out 80 bytes this way as well.
Let's assume that a record (or structure in C++) exists which has a name field followed by two integers, and we will refer to it as theRecord. The structure can be written to disk as follows...
ofstream afile("c:\somefile.txt", ios::binary);
afile.write((char*)&theRecord, sizeof(theRecord));The code (char*) is neccesary to 'cast' the record to a PChar which is required by the fstream write function. If you are familiar with using the Windows API in Delphi you know that Delphi strings must be cast to pointers to character arrays as well (Pchar(TheString) in Delphi code).
The code &theRecord extracts the address of the record and so the bytes in the record starting from this address are cast to a PChar and then this PChar is passed to the write routine and written out to afile. This accomplishes basically the same thing as the Delphi code above and this could also be done using the TFileStream class in Delphi, passing the number of bytes in the record structure as the argument to the writebuffer method of the streaming class. (For some reason I am not clear on, the writebuffer method works while the write method does not, but this could have something to do with the way the internal addresses are used in these two methods). As well, note that if you are reading in a record from disk you must use the same code as above, casting the record structure to a PChar, since the read function of the ifstream class also requires a character pointer as its operand.
When a file is open for read or for read/write it is possible to do random access on the file using the seeking functions provided by both Delphi and C++. (Note that in Delphi you cannot seek using a textfile but rather you must use a typed or, as in the examples above, an untyped file variable). Assume that afile is an untyped file variable...
var afile : file; fpos : longint;
begin
Assignfile(afile, 'C:\something.txt');
Reset(afile, 1);
fpos := sizeof(theRecord) * 122;
Seek(afile, fpos);The Tfilestream class also has a seek method...
var filestream : TFilestream; offset : longint; origin : word;
begin
filestream := TFilestream.create('c:\something.txt', fmopenread);
filestream.seek(offset, origin);Typed and Untyped files can return their file postion using FilePos which returns a longint...
lx := FilePos(afile);
As does TfileStream...
lx := filestream.position;
In C++ the fstream class has a seek function and a file position function, for either the ifstream or the ofstream classes. Seekg() and tellg() seek or return the position for ifstream variables while seekp() and tellp() do the same for ofstream classes. The usage of the functions looks like the following...
ifstream afile("c:\something.txt", ios::binary);
int pos;
afile.seekg(0, pos)
pos = afile.tellg();By opening a file in append mode tellg() would return the size of the file in bytes. By opening an ofstream variable in read/write mode parts of a file could be accessed and changed randomly.
A Unified Field Theory
![]()
The Unified Field Theory
is also available as a zip file -> unified.zip
Introduction :The Pioneer Effect and the New Physics. A brief description of the new physics required to explain the 'Pioneer Effect', which is the constant deceleration of space craft as they fly through space.

