Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
10 views

LAB 15 - Oop

The document provides information about file input/output (I/O) operations in C++ including formatted and unformatted I/O streams, binary write, file modes, the seek and tell functions, and templates and template functions. It includes examples of reading from and writing to files in both text and binary formats.

Uploaded by

abuzarali1124
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

LAB 15 - Oop

The document provides information about file input/output (I/O) operations in C++ including formatted and unformatted I/O streams, binary write, file modes, the seek and tell functions, and templates and template functions. It includes examples of reading from and writing to files in both text and binary formats.

Uploaded by

abuzarali1124
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

National University of Computer & Emerging Sciences, Karachi

Computer Science Department


Spring 2023, Lab Manual 11
Course Code: CL1004 Course : Object Oriented Programming Lab
Instructor(s) : Abeeha Sattar

Contents
 Filing , I/O STREAM ( formatted , unformatted)
 Binary write
 Files modes
 Templates , template function , template classes.

FILING
 Filing in C++ refers to the process of reading from or writing to files.
 Files are used to store data that can be accessed by a program.
 C++ provides a set of file stream classes to perform file operations.
 The ofstream class is used to create and write to files.
 The ifstream class is used to read from files.
 The fstream class can be used for both reading and writing to files.
 Before using a file stream object, you need to open a file using the open() function and
close the file using the close() function when you are done.
 File I/O operations include reading from a file using the >> operator, writing to a file using
the << operator, and using functions like getline() to read a line of text from a file.

I/O STREAM ( FORMATTED , UNFORMATTED )

 In C++, input and output operations are performed using I/O streams.
 I/O streams are a way of abstracting input and output devices, such as the console or files,
as streams of characters.
 C++ supports both formatted and unformatted I/O streams.
 Formatted I/O streams format the output data according to a specified format, such as
decimal or hexadecimal.
 Formatted output is achieved using the insertion operator << to write to a stream and
formatted input is achieved using the extraction operator >> to read from a stream.
 Examples of formatted I/O streams include cout and cin.
 Unformatted I/O streams do not format the output data in any way and simply write or
read the data as-is.
 Unformatted output is achieved using the write() function to write to a stream, and
unformatted input is achieved using the read() function to read from a stream.
 Examples of unformatted I/O streams include fstream and stringstream.
 It is important to properly handle errors that can occur during I/O operations, such as file
not found or data corruption.

BINARY WRITE / OBJECT WRITE


Binary write, also known as object write, is a file I/O operation in C++ that allows you to write
binary data, such as serialized objects or images, to a file. Unlike text mode, binary mode reads
and writes data in its raw binary format, without any translation or formatting.

Here is an example of binary write in C++:


#include <fstream>
#include <iostream>
#include <string>

using namespace std;

class Person {
public:
string name;
int age;
};

int main() {
Person person;
person.name = "John";
person.age = 25;

//writing object to a file


ofstream file("person.bin", ios::binary);
file.write((char*)&person, sizeof(Person));
file.close();

cout << "File written successfully." << endl;


//reading object from a file
Person otherPerson;
ifstream file2;
file2.open("person.bin",ios::in);
file2.seekg(0);
file2.read((char*)&otherPerson,sizeof(Person));
cout << "\nName : " << otherPerson.name << endl;
cout << "\nAge : " << otherPerson.age << endl;
file2.close();
return 0;
}

In this example, we define a Person class with a name and age field. We then create a Person
object and set its name and age. Next, we create an ofstream object to open a binary file in
write mode. We use the write() function to write the Person object to the file in its binary
format. Finally, we close the file and print a message to the console.
Note that when writing binary data to a file, we need to use the reinterpret_cast operator to
cast the Person object to a char pointer, which can be written to the file. We also need to
specify the size of the Person object using the sizeof operator.
Binary write is a powerful tool for serializing objects and storing them in files, which can be
loaded and deserialized at a later time. However, it is important to ensure that the data being
written is in the correct binary format and that the data is being written to the correct location
in the file.

FILE MODES
In C++, file modes are used to specify the type of file operation that you want to perform, such
as read, write, append, or binary mode. Here are the different file modes in C++:
 ios::in: Read mode - allows reading from a file.
 ios::out: Write mode - allows writing to a file.
 ios::app: Append mode - allows writing to the end of a file.
 ios::trunc: Truncate mode - discards the contents of the file before opening it for writing.
 ios::binary: Binary mode - reads and writes data in binary format, without any translation
or formatting.

#include <fstream>
#include <iostream>
#include <string>

int main() {
ofstream myfile;

// Read mode
myfile.open("example.txt", ios::in);

// Write mode
myfile.open("example.txt", ios::out);

// Append mode
myfile.open("example.txt", ios::app);

// Truncate mode
myfile.open("example.txt", ios::trunc);

// Binary mode
myfile.open("example.bin", ios::binary);

myfile.close();

cout << "File operation successful." << endl;


return 0;
}
SEEK FUNCTION
In C++, the seek function is used to move the read/write pointer to a specific location in a file.
The seek function is typically used in conjunction with file I/O operations, such as read and
write, to navigate through the contents of a file.

The seek function is declared in the fstream library and has the following syntax:
streampos seekg(streampos pos);
streampos seekg(streamoff off, ios_base::seekdir way);
streampos seekp(streampos pos);
streampos seekp(streamoff off, ios_base::seekdir way);

Here is a brief summary of the parameters:


pos: the absolute position in the file to move the read/write pointer to.
off: the relative offset to move the read/write pointer.
way: the direction in which to move the read/write pointer, relative to the current position.
Here are the different seek directions:
ios_base::beg: move the read/write pointer relative to the beginning of the file.
ios_base::cur: move the read/write pointer relative to the current position.
ios_base::end: move the read/write pointer relative to the end of the file.

Here is an example of using the seek function in C++:


#include <iostream>
#include <fstream>

int main() {
fstream file("example.txt", ios::in | ios::out);

if (file.is_open()) {
file.seekp(10, ios_base::beg);
file << "Hello World!";
file.seekg(0, ios_base::beg);

string line;
while (getline(file, line)) {
cout << line << endl;
}

file.close();
}

return 0;
}
In this example, we open a file in read/write mode using std::fstream. We then use the seekp()
function to move the write pointer to the 10th byte in the file and write "Hello World!" to the
file. We then use the seekg() function to move the read pointer to the beginning of the file.
Finally, we read the contents of the file using the getline() function and print them to the
console.
The seek function is a powerful tool for navigating through the contents of a file, allowing you
to read, write, and modify data at specific locations in the file. It is important to use the
appropriate seek direction and to properly close the file after performing the desired
operations.
TELL FUNCTION
In C++, the tellg() and tellp() functions are used to return the current position of the read and
write pointers, respectively, in a file. These functions are typically used in conjunction with the
seekg() and seekp() functions to navigate through the contents of a file.

Here is a short example of using the tellp() function in C++:


#include <iostream>
#include <fstream>

int main() {
ofstream file("example.txt", ios::out | ios::app);

if (file.is_open()) {
file << "Hello World!";
streampos position = file.tellp();
cout << "Current position: " << position << endl;
file.close();
}

return 0;
}

GENERICS/ TEMPLATES

Generics is a concept that refers to the ability to write code that can be used with different data
types. In C++, this is achieved through the use of templates, which are code structures that can
be parameterized with one or more types.

In C++, generics and templates are often used interchangeably because templates provide a
way to write generic code. Templates allow you to write code that can work with different data
types without having to write separate implementations for each data type.

Here is an example of a combined use of generics and templates in C++:


#include <iostream>
using namespace std;
template <typename T>
void printValue(T value) {
cout << "Value: " << value << endl;
}

int main() {
int intValue = 42;
double doubleValue = 3.14;
char charValue = 'A';

printValue(intValue); // prints "Value: 42"


printValue(doubleValue); // prints "Value: 3.14"
printValue(charValue); // prints "Value: A"

return 0;
}
In this example, we define a generic function called printValue() using templates. The typename
T syntax declares a type parameter T, which can be any data type. The function takes a single
parameter of type T and prints its value to the console.
In the main() function, we create three variables of different data types (int, double, and char)
and pass each of them to the printValue() function. Since printValue() is a template function, it
can be used with any data type, and will print the value of the parameter passed to it.

TEMPLATE FUNCTION
A template function is a function that is defined using a template parameter, which can
represent any data type. The template parameter is specified using the typename keyword,
followed by a name that is used within the function definition to represent the actual data type.
Here's the basic syntax for defining a template function:
template <typename T>
void functionName(T parameter) {
// function body
}
In this example, functionName is the name of the function, and T is the template parameter.
The typename keyword specifies that T represents a data type, and the function definition can
use T to declare variables, parameters, and return values of that data type.
To call a template function, you specify the actual data type as the template argument when
you call the function.

For example:
functionName<int>(42); // calls functionName with an int parameter
functionName<double>(3.14); // calls functionName with a double parameter

In this example, int and double are the template arguments that specify the actual data types
for the T template parameter.
Template functions are useful when you need to write a function that can work with different
data types, without having to write separate implementations for each data type. Templates
allow you to write generic code that can be reused with different data types, which can save
time and reduce code duplication.

A template function in C++ that finds the maximum element in an array of any data type:
#include <iostream>
using namespace std;
template <typename T>
T maxElement(T* array, int size) {
T max = array[0];
for (int i = 1; i < size; i++) {
if (array[i] > max) {
max = array[i];
}
}
return max;
}

int main() {
int intArray[] = { 4, 2, 5, 1, 3 };
double doubleArray[] = { 3.14, 1.5, 2.7, 4.2 };

int maxInt = maxElement(intArray, 5);


double maxDouble = maxElement(doubleArray, 4);
cout << "Max element in intArray: " << maxInt << endl;
cout << "Max element in doubleArray: " << maxDouble << endl;

return 0;
}

In this example, the maxElement template function takes an array of any data type and its size
as input, and returns the maximum element in the array. The function uses a simple loop
algorithm to traverse the array and find the maximum element. The main program calls the
maxElement function with an array of integers and an array of doubles, and prints the
maximum element for each array. This function can be used with any data type that supports
the greater-than operator (>).

USE OF TEMPLATE FUNCTION ( ANOTHER EXAMPLE)


Suppose you are writing a program for a fitness tracking application that needs to calculate the
body mass index (BMI) of a person. The BMI is calculated using the following formula: weight /
(height * height), where weight is in kilograms and height is in meters.
To calculate the BMI for a person, you need to perform the same calculation regardless of the
person's weight and height data types. A template function can be used to perform this
calculation for any data type.
Here's an example implementation:
#include <iostream>

using namespace std;


template<typename T>
T calculate_bmi(T weight, T height) {
T bmi = weight / (height * height);
return bmi;
}

int main() {
double weight = 75.0; // kilograms
double height = 1.8; // meters
double bmi = calculate_bmi(weight, height);
cout << "BMI: " << bmi << endl;
return 0;
}
In this example, the calculate_bmi function is defined as a template function with a single type
parameter T. This function takes two parameters weight and height of type T and returns the
calculated BMI of type T.
In the main function, we use the calculate_bmi function to calculate the BMI for a person with
weight 75.0 kg and height 1.8 meters. The result is then printed to the console.

Template class

In C++, a template class is a class that is defined with generic type parameters. These
parameters can be used to define member functions, member variables, and the overall
structure of the class.
Template classes are useful because they allow you to write code that is independent of the
specific data types it operates on. For example, you could write a generic container class that
can hold any type of object. This container class could then be used with any data type without
needing to be re-implemented for each specific type.

#include <iostream>

using namespace std;


template<class T>
class MyContainer {
private:
T* data;
int size;
public:
MyContainer(int size=0) {
this->size = size;
data = new T[size];
}
~MyContainer() {
delete[] data;
}
T& operator[](int index) {
return data[index];
}
};
int main() {
MyContainer <int> mycon;
MyContainer <int> mycon2(10);
mycon2[1] = 100;
cout << mycon2[0] << endl << mycon2[1];
}
Another example
Suppose you are writing software for a weather station that can measure different types of
weather data, such as temperature, humidity, and air pressure. You want to create a generic
data structure to store this weather data that can work with any data type.
A template class can be used to create a generic weather data container that can store any data
type for temperature, humidity, and air pressure. Here's an example implementation:
#include

template<typename T>
class WeatherData {
private:
T temperature;
T humidity;
T air_pressure;
public:
WeatherData(T temp, T hum, T press) : temperature(temp), humidity(hum), air_pressure(press)
{}

void print_data() {
cout << "Temperature: " << temperature << " C" << endl;
cout << "Humidity: " << humidity << "%" << endl;
cout << "Air Pressure: " << air_pressure << " kPa" << endl;
}
};

int main() {
WeatherData<double> data1(25.6, 70.2, 101.3);
data1.print_data();

WeatherData<int> data2(20, 65, 100);


data2.print_data();
return 0;
}
In this example, the WeatherData class is defined as a template class with a single type
parameter T. This class has private member variables temperature, humidity, and air_pressure,
all of type T.
The constructor of the class takes three parameters of type T, which correspond to the
temperature, humidity, and air pressure measurements, respectively. The print_data function is
a member function of the class that prints the stored data to the console.
In the main function, we create two instances of the WeatherData class, one with double data
types and the other with integer data types. The print_data function is then called on both
instances to display the stored weather data.
Using a template class in this way allows us to create a single data structure that can store any
type of weather data without needing to define a separate class for each data type.
Tasks:

Question#1:
Write a function “T calculateDeterminat(T **m1, T **m2)” that accepts two, 2D arrays of
dimensions 3x3 (a matrix) and then calculates the determinant for those matrices. You’re
required to create two matrices in your main function, and then call the calculateDeterminant
function that accepts these matrices.
Assume you can input only numbers.

Question#2:
For the above question, write a specialized template for char matrices.
Edit the calculateDeterminant function such that it checks the data type of the matrix. If the
datatype is int, float or double, it should perform its functionality from part 1, otherwise it
should display that the determinant cannot be calculated.
Hint: You can get the type of any variable by the following line of code:
var_type = typeid(varname).getName();

Question#3:
Create a file with the following text (copy paste it please!):
The quick brown fox
Jumps over the
Lazy Dog. It was sad.

Place the file in the same folder as your .cpp file, otherwise you won’t be able to read it directly.
You are required to read this file, and count the following:
 Number of Vowels
 Capital Letters
 Spaces
 Full Stops
Using the seekp/seekg/tellp/tellg methods, move to the 2nd last location(before the full stop),
and write these numbers down, separated by space.
Try to identify by yourself which methods will be needed for this task.
Question#4:
You’re required to make a Reader class, and Writer class for this question. The Reader and Writer
class should be friends of the Student class, so that we can avoid the hassle of using getters and
setters!
For your Student class create a class with the following:
 Student ID
 Student Name
 Batch Number
 Year (Senior/Junior, etc)
 A default constructor
 A parameterized constructor that sets all the values.
For your Writer class:
Create a static public method called writeStd(Student &std), perform filing inside this
function to create as student.bin file (you can use the very first example as a basis for this). Open
the file in append mode so that the data does not get overwritten!
For your Reader class:
Create a static public method called readStd(Student &std), perform filing inside this
function to read the student.bin file. Add a loop here to read all the student objects stored in the
file. It should display all the details for the students fetched from the file.
In your main() :
 Create a student object by asking for user’s input.
 Use your static write method to write the data to the .bin file.
 Use your static read method to read all the data in the file.
 Run your program multiple times to see if it works correctly.

You might also like