LAB 15 - Oop
LAB 15 - Oop
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.
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.
class Person {
public:
string name;
int age;
};
int main() {
Person person;
person.name = "John";
person.age = 25;
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();
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);
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.
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.
int main() {
int intValue = 42;
double doubleValue = 3.14;
char charValue = '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 };
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 (>).
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>
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();
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.