Computer programming -
Algorithms
Semester 2
Module 2
English classes
1
C++ Files
• To perform I/O operations with files, the program must
include the header file/namespace fstream, which defines
several classes:
- ifstream, ofstream and fstream
• These classes are derived from istream and ostream classes
• In C++, a file is opened by connecting it to a stream
• Before opening the file, it must first be obtained a stream
• To create an input stream, it must be declared as type
ifstream and to create an output stream, it must be declared of
type ofstream
• Streams carrying out both operations must be declared by
type fstream
• Examples:
ifstream in;
ofstream out;
fstream io; 2
Opening/closing a file
• The open( ) method is used to associate a file to a stream
• This method is a member of all three classes of stream
type and has the prototype:
void open(char * filename, int mode, int access = filebuf ::
openprot);
- The first parameter is a pointer to the filename
- The mode parameter is a value that specifies how to
open the file
• possible values for the second parameter are defined in
the ios class as follows:
3
• enum open_mode{
in = 0x01, // input file
out = 0x02, // output file
ate = 0x04, //after opening the current position will be the end of file
app = 0x08, // open to append (write at the end of the file)
trunc = 0x10, /* if the file exists the content will be deleted (implicit option
for an output file if options "ios::app" or "ios::ate" is not used) */
nocreate = 0x20, // if the file does not exist, is thrown an error
noreplace = 0x40, // no opening if file exists
binary = 0x80 // opening in binary mode
};
Values that can be used by the programmer are: ios::in, ios::out, ios::ate,
ios::app, ios::trunc, ios::nocreate, ios::noreplace, ios::binary, with the
significance presented in the enumeration.
4
• Combinations of mode specifiers are allowed using
"logical OR, |" bitwise
ifstream f1;
f1.open("name", ios::in | ios::nocreate)
Or is equivalent with:
ifstream f1("name", ios::in | ios::nocreate);
• mode parameter has default values (not for all IDE!!!):
- for an object of type ifstream default parameter mode is
ios:: in
- for an ofstream object is ios:: out | ios::trunc
• - for a fstream object is: ios::in | ios::out (not available for
some compilers)
• access parameter determines the file access;
• filebuf:: openprot (filebuf is the parent class of stream
type classes) is the default value, which corresponds to
DOS attribute codes: 5
• Attribute Significance
0 normal-access file type “open”
1 “read-only” file
2 hidden file
4 system file
8 archive
The code to open a normal output file with test name will be :
ofstream out;
out.open("test", ios::out | ios:trunc, 0);
Therefore, the above syntax statement can be simplified:
out.open("test"); or,
ofstream out("test"); //because open is not compulsory
• We may generalize: ifstream fin("test"); // in file
ofstream fout("test"); // out file
fstream finout("test"); // in-out file 6
• To open a stream for input and output operations, if not
accepted the defaults listed above, you must specify the
value of ios:: in, ios:: out as well.
fstream own_stream;
own_stream.open("test", ios::in | ios::out);
• For access parameter we can use non default values:
filebuf::sh_none exclusive open (no share);
filebuf::sh_read read sharing;
filebuf::sh_write write sharing.
• Last two may be combined with logical OR.
• If the open operation fails, the file stream will be zero.
• Before using a file, it is important to check if the open
operation was successful, using a code sequence like:
if (! own_stream) {cout<< "Not possible to open the file\n";
// error
7
}
• We can use the method is_open( ) to test whether a file
has been properly connected to a stream:
bool is_open( ); //true correct open, false otherwise
• To close a file, we use the member method close( ).
• Method close( ) has no parameters and returns no value.
To close a file called own_stream coupled to a stream, we
use the construction:
own_stream.close( );
• After opening a file, if the file was opened in text mode
(default mode), it is easy to read/write data from/into it.
Use stream operators (<<) and (>>) with various types of
data in a similar manner to that used in I/O operations,
from/to the console, except that instead of cin and cout is
used the user stream coupled to file.
• It is also possible to use the binary methods put( ), get( )
and getline( ) for a string of characters to manage text. 8
Example: Create/read file
#include <iostream>
#include <fstream>
using namespace std;
constexpr int dim =80;
int main( ){
ofstream fout ("test.txt");// open an output file
if (!fout) { cout<<" Unable to open output file \n"; exit(1);}
fout<<"Salut!\n";
fout<<100<<' '<<hex<<100<<endl;
fout.close( );
ifstream fin("test.txt"); // open an input file
if (!fin){ cout<<" Unable to open input file \n"; exit(1);}
char sir[dim]; int i,j;
fin>>sir>>i>>j;
cout<<sir<<' '<<i<<' '<<j<<endl;
fin.close( );
}//main 9
//write string, double and int values separated by space
#include <iostream>
#include <fstream>
using namespace std;
constexpr int dim=20;
int main( )
{
ofstream out("test.txt"); // output, normal file
if(!out) {
cout << "Cannot open test.txt file.\n";
exit(1);
}
out << "R " << 9.9 <<" "<< 10<< endl;
out << "T " << 9.9 <<" "<< 9 << endl;
out << "M " << 4.8 <<" "<< 4 <<endl;
out.close( );
10
ifstream in("test.txt"); // input
if(!in) {
cout << "Cannot open test.txt file.\n";
exit(1);
}
char item[dim];
double cost;
int mark;
in >> item >> cost >>mark;
cout << item << " " << cost <<" "<< mark<< "\n";
in >> item >> cost >>mark;
cout << item << " " << cost <<" "<< mark<< "\n";
in >> item >> cost >>mark;
cout << item << " " << cost <<" "<< mark<< "\n";
in.close( );
11
}//main
Same example managing the eof( )
//write string, double and int values separated by space
#include <iostream>
#include <fstream>
using namespace std;
constexpr int dim=20;
int main( )
{
ofstream out("test.txt"); // output, normal file
if (!out) {
cout << "Cannot open test.txt file.\n";
exit(1);
}
out << "R " << 9.9 << " " << 10 << endl;//standard overloading
out << "T " << 9.9 << " " << 9 << endl;
out << "M " << 4.8 << " " << 4 << endl;
//out<<std::ifstream::traits_type::eof( ); //write EOF
12
out.close( );
ifstream in("test.txt"); // input
if (!in) {
cout << "Cannot open test.txt file.\n";
exit(1);
}
char item[dim];
double cost;
int mark;
/* int eof_m;
while (1){
in >> item >> cost >> mark;
if (eof_m = in.peek( ), eof_m == -1)break;
cout << item << " " << cost << " " << mark << "\n";
};*/
while (in) { //while (1) {
in >> item >> cost >> mark;
if (in.eof( )) break;
cout << item << " " << cost << " " << mark << "\n";
}
in.close( );
}//main
13
// program that writes / reads different data in/from a file
#include <iostream>
#include <fstream>
using namespace std;
constexpr int dim = 11;
int main( ) {
const char sir[dim] = "ABCDEFGHIJ";
char fsir[dim];
int mark = 10, fmark;
double media = 9.5, fmedia;
fstream io;
io.open("test.txt", ios::out);
if (!io) {
cout << "Can not open the output file\n";
exit(1);
}
io << sir << " " << mark << " " << media << endl;
//io<<"jhgfsjdgah "<<mark<<" "<<media<<endl;
io.close( );
14
io.open("test.txt", ios::in);
if (!io) {
cout << "Can not open the input file\n"; exit(1);}
while (1) {
io >> fsir >> fmark >> fmedia;
if (io.eof( )) break;
cout << fsir << endl << fmark << endl << fmedia << endl;
}
io.close( );
}//main
15
I/O binary files
• C++ provides for binary files opened with ios::binary
binary methods, get( ) and put( ) used at physical level.
With the member method put( ) we write a byte and with
the method get( ) we read a byte.
The prototype of get( ) method is:
istream& get(char& car);
• The method reads from the associated stream one
character and place the value in variable car. The
method returns a reference to the input stream.
The prototype of method put( ) is :
ostream& put(char car);
• The method writes the character car in stream and
returns a reference to the output stream.
• To read a string of characters we can use the getline( ),
with the following syntax: 16
istream& getline(char* sir, int nr_max, char delim= '\n');
• will be read till the meeting of the delimiter or nrmax-1
characters. It is suitable for reading lines of text files.
• To read/write blocks of binary data, are used methods
read( ) /write( ), which have the following prototype:
istream& read(unsigned char *buf, int number);
ostream& write(const unsigned char *buf, int number);
• Method read( ), reads the number of bytes in the stream and
puts them in the buffer associated with pointer buf.
Method write( ), writes from the buffer zone, pointed by buf, a
number of bytes in the associated stream.
• Other methods presented for in/out operations are able to be
used.
17
Example read( ) method:
// read( ) method to read from a created file
#include <iostream>
#include <fstream>
using namespace std;
constexpr int dim=13;
int main( ) {
char sir[dim] = " ";
fstream io;
io.open("test.txt", ios::out);
if (!io) {
cout << "Can not open the output file\n"; exit(1);
}
io.write("qweqweqweqwe\n", dim);//using write method to file
io << "jhgfsjdgahj\n";//write by standard overloading
io << "abcabcabcab\n";
//io<<std::ifstream::traits_type::eof( ); //write EOF
io.close( ); 18
io.open("test.txt", ios::in);
if (!io) {
cout << "Can not open the input file\n";
exit(1);
}
while (io) { //while (1) {
io.read(sir,dim-1);
if (io.eof( )) break;
cout << sir<<endl;
}
io.close( );
}//main
19
// get( ) example
#include <iostream> // std::cin, std::cout
#include <fstream> // std::ifstream
//using namespace std;
constexpr int dim=25;
int main ( ) {
char str[dim];
std::fstream io ;
std::cout << " File to generate \n";
io.open("test.txt", std::ios::out);
if (!io) {
std::cout<< "Can not open the output file\n";
exit(1);}
io.write("\nTest string to check ", dim);
//io<<"\njhgfsjdgahjs";
io.close( ); 20
std::cout << "Enter the name of an existing test.txt file:
";
std::cin.get (str,dim); // get c-string
std::ifstream is(str); // open file
while (is.good( )) // loop while extraction from file is
possible
{
char c = is.get( ); // get character from file
if (is.good( ))
std::cout << c;
}
is.close( ); // close file
}//main
21
getline( ) example:
//getline_example
#include <iostream>
using namespace std;
#include <fstream>
constexpr int dim_f = 65;
constexpr int dim = 101;
int main( ) {
char infname[dim_f];
char outfname[dim_f];
char buffer[dim];
cout << "Source file: ";
cin >> infname;
ifstream in(infname);
if (!in) {
cout << "Can not open the file: " << infname << endl;
exit(1);
}
22
cout << "Out file: ";
cin >> outfname;
ofstream out(outfname);
if (!out) {
cout << "Can not open the file: " <<
outfname << endl;
exit(1);
}
while (in) { //while (1) {
in.getline(buffer, dim - 1); // read text line
if (in.eof( )) break;// test eof
out << buffer << endl; // write text
}
cout << "Finished";
in.close( );
out.close( );
}//main 23
Example read/write, getline:
#include <iostream>
using namespace std;
#include <fstream>
constexpr int dim =20;
constexpr int dim_s =8;
int main ( ){
int numar =12;
ofstream OUT ("test.txt"); // out file
if (!OUT) {
cout<< "Can not open the output file\n";
return 1;
}
OUT.write("Salut !\n", dim_s);
OUT.write((char *)&numar, sizeof(int));
OUT.close( );
24
ifstream IN ("test.txt");
if ( !IN ) {
cout<< "Can not open the input file\n";
return 1;
}
char sir[dim];
IN.getline(sir, dim-1);
IN.read ((char*) &numar, sizeof(int));
cout << sir << ' ' << numar << endl;
IN.close( ) ;
}//main
25
Read/write objects with EOF management
//Coord.h
class Coord {
int x, y;
public:
Coord( ) { x = 0; y = 0; }
Coord(int i, int j) { x = i; y = j; }
friend ostream& operator<< (ostream&, Coord ob);
friend istream& operator>> (istream&, Coord& ob);
friend ofstream& operator<< (ofstream&, Coord ob);
friend ifstream& operator>> (ifstream&, Coord& ob);
};
// inserter for class Coord
ostream& operator<< (ostream& stream, Coord ob){
stream << "Coordinates are: ";
stream << ob.x << ", " << ob.y << '\n';
return stream;
}
// extractor for class Coord
istream& operator>> (istream& stream, Coord& ob){
cout << "Enter coordinates for the new point: ";
stream >> ob.x >> ob.y;
return stream;
} 26
// file inserter for class Coord
ofstream& operator<< (ofstream& streamf, Coord ob){
streamf << ob.x << " " << ob.y << '\n';
return streamf;
}
// file extractor for class Coord
ifstream& operator>> (ifstream& streamf, Coord& ob){
streamf >> ob.x >> ob.y;
return streamf;
}
// main
#include <iostream>
#include <fstream>
using namespace std;
#include "Coord.h"
int main( ){
ofstream fout;
ifstream fin;
fout.open("test.txt", ios::out | ios::trunc);
if (!fout) {
perror("Cannot open test.txt file.\n");
exit(1);
27
}
Coord A(7, 2), B(17, 20);
cout << A << B;
//cout << "\nWrite A (7,2) and B(17,20) in file\n";
fout << A << B;
cin >> A;
//cout << "\nNew introduced values are: \n";
cout << A;
fout << A;
//fout << std::ifstream::traits_type::eof();// write EOF
fout.close();
fin.open("test.txt");
if (!fin) { perror("Cannot open test.txt file.\n"); exit(1); }
while (fin) { //while (1) {
fin >> A;
if (fin.eof( )) break;
cout << A;
}
//while (!fin.eof( )) {//read twice the last value - past the end
// fin >> A; cout << A;
//}
fin.close( );
return 0;
28
}//main
Random access files
• In the I/O system in C++, we have access in direct mode
to files randomly, using seekg( ) and seekp( ) methods.
Most common forms for these methods are:
istream& seekg(streamoff offset, seek_dir origin) ;
ostream& seekp(streamoff offset, seek_dir origin) ;
Type streamoff is defined by iostream and contain the max
value of offset and seek_dir is an enum with 3 possible
values for origin: ios::beg, ios::cur, ios::end.
Position (absolute, relative to the starting position) of the
stream can be obtained for get files with the method:
long tellg( ) ;
• Current position (the absolute, relative to the starting
position) can be achieved for put files with the method:
long tellp( ) ; 29
Example random files:
• /* The program described in the following example will illustrate
working with the seekp() method. It will allow us to change a certain
character in a file; it is necessary to specify a name in the command
line, followed by the position of the character we want to change and
the new character. The file will be opened for read / write operations.
*/
#include <iostream>
#include <fstream>
using namespace std;
int main( int argc, char*argv[ ] ){
if(argc!=4){
cout << "Use: Fis_Exe < file_name> <no_byte> <new_char>\n" ;
//>random_file test.txt 0 A
exit(1);
}
30
fstream out;
out.open(argv[1],ios::in | ios::out | ios::binary) ;
if(!out){
cout<<" Cannot open file ";
exit(1);
}
out.seekp(atoi(argv[2]),ios::beg) ;
out.put(*argv[3] ) ;
out.close( ) ;
}//main
31
Files with classes complete example- lab. problem
//Fisier.h
class Fractie {
int a;
int b;
void simplify();
public: Fractie();
Fractie(int j, int k);
void setA(int x) { a = x; }
void setB(int y) { b = y; }
int getA() { return a; }
int getB() { return b; }
Fractie& operator ++();//prefixed
Fractie operator ++(int);//postfixed
Fractie& operator --();//prefixed
Fractie operator --(int);//postfixed
friend Fractie operator+ (Fractie x, Fractie y);
friend Fractie operator- (Fractie x, Fractie y);
friend Fractie operator* (Fractie x, Fractie y);
friend Fractie operator/ (Fractie x, Fractie y);
friend std::ostream& operator<< (std::ostream& stream, Fractie ob);
friend std::istream& operator>> (std::istream& stream, Fractie& ob);
friend std::ofstream& operator<< (std::ofstream& stream, Fractie ob);
friend std::ifstream& operator>> (std::ifstream& stream, Fractie& ob);
};//Fractie
32
//Implementare
Fractie::Fractie() {
a = 0;
b = 1;
}
Fractie::Fractie(int j, int k) {
a = j;
if (k != 0) b = k;
else { cout << "\nNumitorul nu poate fi 0!- pus pe 1"; b=1; }
}
void Fractie::simplify() {
if (a == 0 || b == 0) {
a = b = 0; return; }
int c = abs(a);
int d = abs(b);
while (c != d) {
if (c > d)c = c - d;
else d = d - c; }
a = a / d;
b = b / d;
}
Fractie& Fractie:: operator ++() {//prefixed
a= a + b;
return *this;
}
Fractie Fractie:: operator ++(int) {//postfixed
Fractie ob=*this;
++(*this);
return ob;
} 33
Fractie& Fractie:: operator --() {//prefixed
a = a - b;
return *this;
}
Fractie Fractie:: operator --(int) {//postfixed
Fractie ob = *this;
--(*this);
return ob;
}
Fractie operator+ (Fractie x, Fractie y) {
Fractie s;
if (x.b == y.b) {
s.a = y.a + x.a;
s.b = y.b;
}
else {
s.a = (y.b * x.a) + (x.b * y.a);
s.b = (x.b * y.b);
}
s.simplify();
return s;
}
Fractie operator- (Fractie x, Fractie y) {
Fractie s;
if (x.b == y.b) {
s.a = x.a - y.a;
s.b = y.b;
} 34
else {
s.a = (y.b * x.a) - (x.b * y.a);
s.b = (x.b * y.b); }
s.simplify();
return s;
}
Fractie operator* (Fractie x, Fractie y) {
Fractie s;
s.a = x.a * y.a;
s.b = x.b * y.b;
s.simplify();
return s;
}
Fractie operator/ (Fractie x, Fractie y) {
Fractie s;
s.a = x.a * y.b;
s.b = x.b * y.a;
s.simplify();
return s;
}
istream& operator >> (istream& stream, Fractie& ob) {
cout << "Cititi numaratorul: "; stream >> ob.a;
cout << "Cititi numitorul: "; stream >> ob.b;
if (ob.b == 0) { std::cout << "\nNumitorul nu poate fi 0!!! = 1"; ob.b=1; }
return stream;
}
ostream& operator<< (ostream& stream, Fractie ob) {
stream << "Numitorul este: " << ob.a;
stream << " " << " Numaratorul este: " << ob.b;
return stream; 35
}
Source . cpp
ifstream& operator>> (ifstream& stream, Fractie& ob) {
stream >> ob.a >> ob.b;
return stream;
}
ofstream& operator<< (ofstream& stream, Fractie ob) {
stream << ob.a << ' ' << ob.b << endl;
return stream;
}
//main()
#include <fstream>
#include <iostream>
using namespace std;
#include "Fisier.h"
int main( ) {
Fractie ob1, ob2, o3, o4, o5, o6, ppo,opp;
cin >> ob1;
cin >> ob2;
o3 = ob1 + ob2;
o4 = ob1 - ob2;
o5 = ob1 * ob2;
o6 = ob1 / ob2;
cout << "Obiectele initiale " << endl << "Ob1: " << ob1 << endl << "Ob2: " << ob2;
cout << endl << "Suma lor: " << o3;
cout << endl << "Diferenta lor: " << o4;
cout << endl << "Produsul lor: " << o5;
cout << endl << "Catul lor: " << o6;
36
cout << "\nObiectul initial Ob1: " << ob1;
opp = ob1++;
cout << endl << "Rez_Postfix: opp = ob1++, opp: " << opp;
cout << endl << "Rez_Postfix: opp = ob1++, ob1: " << ob1;
cout << "\nObiectul initial Ob2: " << ob2;
ppo = ++ob2;
cout << endl << "Rez_Prefix: ppo = ++ob2, ppo " << ppo;
cout << endl << "Rez_Prefix: ppo = ++ob2, ob2: " << ob2;
cout << "\nObiectul initial Ob1: " << ob1;
opp = ob1--;
cout << endl << "Rez_Postfix: opp = ob1--, opp: " << opp;
cout << endl << "Rez_Postfix: opp = ob1--, ob1: " << ob1;
cout << "\nObiectul initial Ob2: " << ob2;
ppo = --ob2;
cout << endl << "Rez_Prefix: ppo = --ob2, ppo " << ppo;
cout << endl << "Rez_Prefix: ppo = --ob2, ob2: " << ob2;
Fractie of1, of2, of3, of4, of5, of6, ppob1, ob2pp;
ofstream fout;
fout.open("fractie.dat");
fout << ob1 << ob2;
fout << o3;
fout << o4;
fout << o5;
fout << o6;
fout << ++ob1;
fout << ob2--;
fout.close();
cout << "\n Datele au fost scrise in fisierul: fractie.dat\n"; 37
ifstream fin;
fin.open("fractie.dat");
fin >> of1 >> of2;
fin >> of3;
fin >> of4;
fin >> of5;
fin >> of6;
fin >> ppob1;
fin >> ob2pp;
fin.close();
cout << "\n Datele au fost citite din fisierul: fractie.dat\n";
cout << "Obiectele citite din fisier " << endl << "Of1: " << of1 << endl << "Of2: " << of2;
cout << endl << "Suma lor: " << of3;
cout << endl << "Diferenta lor: " << of4;
cout << endl << "Produsul lor: " << of5;
cout << endl << "Catul lor: " << of6;
cout << endl << "++ob1 din fisier: " << ppob1;
cout << endl << "ob2-- din fisier: " << ob2pp;
}//main
38
I/O character string operations in
C++
• Header file strstream.h or namespace sstream, or in
some IDE contains definitions of classes, ostrstream,
istrstream, strstream that implement the I/O on arrays of
characters (or the equivalent of the name space).
Insertion or extraction on these flows is through arrays of
characters (dynamic or static)
• Specified classes are similar to those for files, being
derived from iostream classes and therefore inherit their
member methods.
• For example, for input operations we can use class
member methods from istream (get( ), read( ), getline( ))
and for output we can use class member methods from
ostream (put( ), write( )). 39
ostrstream class
ostrstream (void); // creates an ostrstream object with
the dynamically allocated buffer zone
ostrstream (char *buf, int size, int mode = ios::out); // the user
specifies the buffer area and its size
char* pcount (void); // gives the number of bytes stored in
the buffer for an output stream
char* str (void); // blocks and returns the buffer associated
with the stream; if it has been allocated dynamically, it must
be deallocated explicitly
Example: ostrstream odyn;
char *buf = odyn.str( ); …
delete buf;
char buffer[1024];
ostrstream ssta(buffer, 1024); 40
#include <strstream>
#include <iostream>
using namespace std;
constexpr int dim =80;
int main( )
{
char str[dim];
ostrstream outs(str, sizeof(str));
outs << 125 << " " << 17.25 <<" astea sunt numerele";
outs << ends; // null terminator
cout <<"Numarul de caractere="<< outs.pcount( )<<endl;
// displays the number of characters from outs
cout << str<<endl;
return 0;
}//main
41
istrstream class
– istrstream (const char *); // creates an istrstream
object that uses a given string
– istrstream (const char *, int n); // creates an
istrstream object that uses the first n bytes in a given
string (more secure!)
Example:
char data[128];
//...
istrstream istr(data, 128);
or
istrstream istr(data);
42
#include <iostream>
#include <strstream>
using namespace std;
const int dim=100;
int main( ) {
istrstream s("15 10.75 Test pentru istrstream ");
int i;
float f;
char buf[dim];
s >> i >> f>> buf; //the inputs are delimited by white spaces
cout << "i = " << i << ", f = " << f<<", buf = " << buf << endl;
cout << s.rdbuf( ); //we display the rest of the istrstream object
return 0;
} //main
43
strstream class
– strstream (void); // as at ostrstream
– strstream (char *buf, int size, int mode); // as at
ostrstream
– char* str (void); // blocks and returns the buffer
associated with the stream; if it has been allocated
dynamically, it must be deallocated explicitly
#include <iostream>
#include <strstream>
using namespace std;
const int dim =20;
int main( ) {
strstream s;
int i; double f; char sir[dim];
s<<"8.75 2116 este media la programare"<<ends;
s>>f>>i>>sir;
cout<<f<<" "<<sir<<" "<<s.str( )<<" a grupei "<<i<<endl;
return 0;
44
}//main