Unit-5 Programming Fundamentals
Unit-5 Programming Fundamentals
1. File Handling
1.1 Introduction to File Handling
In programming, file handling is a way to manage, store, and retrieve data permanently. Unlike
variables that lose their value when a program ends, files provide a means to store data
persistently, allowing data to be accessed and modified even after the program exits.
• Persistence of Data: Files enable data to be stored permanently on storage devices, unlike
variables in memory, which are cleared once a program ends.
• Data Management: Through files, we can store, retrieve, and manipulate large sets of data.
• Easy Access and Sharing: Storing data in files allow it to be accessed, shared, and reused by
different parts of a program or even different programs.
• Data Security: Files provide a way to save data securely, as they can be protected and only
accessed by authorized users or programs.
Types of Files in C
1. Text Files: Stores data in human-readable format, using ASCII characters. Examples include
.txt, .csv, etc.
2. Binary Files: Stores data in binary form, which is more compact and often faster for programs
to read and write. Binary files are generally used for data that should not be read or edited
directly by humans (e.g., image files, executable files).
1. Opening a File: Before we can read or write data to a file, it must be opened.
2. Reading from a File: Reading data stored in a file and storing it in variables or displaying it to
the user.
3. Writing to a File: Writing data from the program into the file for storage.
4. Closing a File: When file operations are complete, the file must be closed to free up resources.
• fopen(): Opens a file and returns a pointer to it. The function requires the file name and the
mode (read, write, etc.).
• fclose(): Closes an open file.
• fgetc(), fgets(): Reads characters or strings from a file.
• fputc(), fputs(): Writes characters or strings to a file.
• fread() and fwrite(): Reads from and writes to binary files.
1.2 Declaration of Files
In C programming, file handling begins with declaring a file pointer. This pointer represents
the file and provides access to its contents during the program’s execution. C uses the standard
FILE structure, defined in the stdio.h library, to manage files.
To work with files, you declare a file pointer of type FILE. This pointer is used to reference the
file throughout the program.
Syntax:
FILE *filePointer;
Here:
• FILE is a structure defined in stdio.h that holds information about a file, such as its current
position and its buffer.
• *filePointer is a pointer to this FILE structure, which will represent the file during
operations.
Example Declaration:
FILE *file;
This statement declares a file pointer named file. We use this pointer to open, read, write, and
close the file as needed.
After declaring a file pointer, we use the fopen() function to open the file and assign its
address to the pointer. The fopen() function requires two arguments:
Syntax:
Modes in fopen():
• "r": Opens a file for reading. The file must exist; otherwise, NULL is returned.
• "w": Opens a file for writing. If the file exists, its contents are erased. If it doesn’t exist, a new
file is created.
• "a": Opens a file for appending data. Data will be written at the end of the file. If the file
doesn’t exist, it will be created.
• "r+": Opens a file for both reading and writing. The file must exist.
• "w+": Opens a file for both reading and writing. If the file exists, it’s overwritten; if not, a new
file is created.
• "a+": Opens a file for reading and appending. If it exists, data can be added to the end;
otherwise, a new file is created.
In this example:
It’s good practice to check if the file was opened successfully, as failing to open a file can cause
runtime errors.
Example:
In this code:
Once all operations on the file are complete, the fclose() function should be used to close it.
This releases resources associated with the file, such as the file pointer and buffer.
Syntax:
fclose(filePointer);
fclose(file);
Closing files is important to avoid memory leaks and ensure data is saved correctly. If you
forget to close a file, data may not be written to the file, especially when dealing with buffered
output.
1.3 Types of Files
In C programming, files are broadly categorized into two types based on how data is stored and
accessed:
1. Text Files
2. Binary Files
Understanding the differences between these types is essential to choose the right file format
for data storage based on readability, file size, and ease of manipulation.
1. Text Files
A text file stores data in a human-readable form, using ASCII characters. Each line in a text
file typically ends with a newline character (\n), and each data value is usually separated by a
space, comma, or other delimiter.
• Larger file size compared to binary files, as each character is stored separately.
• Reading and writing data can be slower, especially with large datasets.
• Not suitable for complex data structures or high-efficiency requirements.
In this code:
A binary file stores data in binary format, which is not human-readable. Binary files are
typically more compact than text files because data is stored in a raw format that does not
require delimiters or character encoding like ASCII.
• Compact size, as binary files do not store characters as ASCII but in binary form, which reduces
storage needs.
• Faster data access and processing because there is no need to interpret ASCII encoding.
• Suitable for large datasets, complex data structures, and applications that prioritize efficiency
(e.g., multimedia files, database storage).
In this code:
Use Case Simple data, logs, configs Multimedia, databases, large datasets
In C programming, a file pointer is a pointer of type FILE that provides access to a file and
allows us to perform various operations, such as reading, writing, and updating data in a file.
It acts as a handle to the file and is used to keep track of the current position within the file
during operations.
The FILE structure, defined in the stdio.h library, holds information about the file being
accessed, including:
FILE *filePointer;
Here:
To use a file pointer, you must initialize it by associating it with a specific file. This is done
using the fopen() function, which takes the file name and the mode (e.g., read or write) as
arguments. fopen() opens the file and returns a file pointer that points to the start of the file.
Syntax:
If the file is opened successfully, fopen() returns a pointer to the file, which is then assigned
to filePointer. If the file cannot be opened (e.g., if it does not exist in "read" mode), fopen()
returns NULL.
In this example:
1. Reading from a File: Use functions like fgetc(), fgets(), or fread() to read data
from the file. The file pointer moves automatically to the next position after each read
operation.
Example:
char ch;
FILE *file = fopen("example.txt", "r");
if (file != NULL) {
while ((ch = fgetc(file)) != EOF) {
printf("%c", ch); // Prints each character
}
fclose(file);
}
2. Writing to a File: Use functions like fputc(), fputs(), or fwrite() to write data to
the file. The file pointer moves to the next position after each write operation.
Example:
3. Repositioning the File Pointer: You can use fseek() or rewind() to change the
position of the file pointer. This is useful for navigating within a file.
o fseek(): Moves the file pointer to a specific position.
o rewind(): Moves the file pointer to the beginning of the file.
Example:
fclose(file);
• Track Position: File pointers keep track of the current position, allowing for sequential reading
or writing.
• Error Handling: By checking if a file pointer is NULL, we can handle errors gracefully (e.g., when
a file fails to open).
• Efficient Resource Management: Closing files when done prevents memory leaks and ensures
data is saved correctly.
File Input/Output (I/O) in C is essential for reading data from files and writing data to files,
which allows programs to interact with external data sources or save data permanently. By
using file I/O, we can perform operations like reading a text file, saving data logs, or processing
input files for calculations.
Opening a File
To perform file I/O, we must first open a file. The fopen() function is used to open a file in a
specific mode (e.g., reading, writing).
Syntax:
Closing a File
After completing all file operations, it is essential to close the file using fclose(). This ensures
that all data is correctly saved, and resources are freed.
fclose(file);
1. Data Logging: Programs often log their output to a file for later analysis. For example,
saving temperature data from a sensor.
2. Configuration Files: Programs may read settings from a file to configure how they
run, such as loading display settings or user preferences.
FILE *configFile = fopen("config.txt", "r");
char setting[50];
fgets(setting, 50, configFile); // Read configuration setting
fclose(configFile);
3. Data Processing: Programs can read data files to perform calculations or analyses, such
as processing sales data or scientific measurements.
File operations in C allow interaction with files through functions that read, write, and
manipulate data. These operations are essential for applications that need to store and retrieve
data persistently.
1. Opening a File: The fopen() function is used to open a file and establish a connection
between the file and a FILE pointer.
fclose(file);
char ch = fgetc(file);
char line[100];
fgets(line, sizeof(line), file);
int data[10];
fread(data, sizeof(int), 10, file);
4. Writing to a File:
o fputc(): Writes a single character.
fputc('A', file);
o fputs(): Writes a string.
rewind(file);
6. Error Handling: Checking the return values of file operations helps ensure that
operations are successful.
if (file == NULL) {
printf("File could not be opened.\n");
}
Example: Writing and Reading a File
#include <stdio.h>
int main() {
FILE *file;
return 0;
}
This example demonstrates:
Error handling is a critical aspect of file operations in C, as it ensures that programs can handle
unexpected situations gracefully, like a file not being available or permission errors. Proper
error handling allows a program to detect issues, inform the user, and prevent potential crashes.
When opening a file using fopen(), it is essential to check if the returned FILE pointer is NULL.
A NULL pointer indicates that the file could not be opened, often due to reasons such as:
Example:
The perror() function displays a descriptive error message related to the most recent file
operation that failed. It’s helpful for debugging as it provides system-specific error information.
Example:
if (file == NULL) {
perror("File opening failed");
}
The ferror() function checks if an error has occurred during file operations like fread() or
fwrite(). This function is useful to verify the integrity of file operations.
Syntax:
Example:
FILE *file = fopen("data.txt", "r");
if (file == NULL) {
perror("Error opening file");
return 1;
}
The clearerr() function resets the error and end-of-file indicators for a file. This can be useful
if you want to attempt another file operation after an error has occurred.
Syntax:
clearerr(file);
Example:
The feof() function checks if the end of the file has been reached. It is helpful when reading
files with unknown sizes or reading until the end.
Syntax:
Example:
In many cases, it’s useful to display custom error messages to give users a more precise
understanding of the issue. For example, when attempting to open a file, you can specify the
exact reason why the operation failed.
Example:
File handling in C is a crucial tool in real-world applications, enabling the storage, retrieval,
and manipulation of data in a persistent format. Below are some practical applications that
illustrate the importance of file handling:
1. Data Logging
File handling is essential for logging information over time, such as system events, user actions,
or application performance metrics. A log file can record events, errors, and other runtime
details that developers can analyze for debugging or optimizing applications.
Example:
#include <stdio.h>
#include <time.h>
Applications often require configuration files to store settings and preferences, allowing users
to modify these without altering the source code. Configurations like screen resolution, theme,
and user preferences are typically stored in text files.
Example:
#include <stdio.h>
#include <string.h>
void readConfig() {
FILE *file = fopen("config.txt", "r");
if (file == NULL) {
perror("Error opening config file");
return;
}
char key[50], value[50];
while (fscanf(file, "%s = %s", key, value) != EOF) {
printf("Key: %s, Value: %s\n", key, value);
}
fclose(file);
}
File handling allows a program to maintain a database of student information, including names,
grades, and other details. This application is essential for educational software, where student
data can be saved and retrieved across sessions.
Example:
#include <stdio.h>
4. Inventory Management
File handling can be used in inventory management to keep track of product details, stock
levels, prices, and other data. This is crucial for retail or warehouse applications that need to
read and update product information regularly.
Example:
#include <stdio.h>
Applications may need to collect and store customer feedback for later analysis. File handling
allows the storage of feedback data that can later be reviewed and processed for quality
assurance and improvement purposes.
Example:
#include <stdio.h>
A simple password management system can use file handling to store encrypted passwords,
allowing for basic authentication functionality. While not suitable for production-grade
security, it can be used in small applications.
Example:
#include <stdio.h>
#include <string.h>
File handling is commonly used to generate, store, and retrieve sales or financial reports. These
reports are critical for businesses, as they contain information on daily transactions, revenue,
expenses, and other financial metrics.
Example:
#include <stdio.h>
Many scientific applications require processing large data files for analysis. File handling
enables the reading of these large datasets, making it possible to analyze and visualize data in
a structured way.
Example:
#include <stdio.h>
OOP differs significantly from procedural programming, where functions and data are typically
separated. In OOP, data (attributes or properties) and functions (called methods) that operate
on the data are bundled together in objects. Let's discuss some key components of OOP.
1. Classes: A class is like a blueprint that defines the structure and behavior (methods) of
an object. For example, a Car class might define properties like color, model, and year
and methods to start, stop, and accelerate the car.
2. Objects: An object is an instance of a class. When we create an object from a class, we
bring the blueprint to life, assigning specific values to its properties and using its
methods to perform actions.
The example below defines a Car class in Java and then creates an object (or instance) of that
class.
• Class Definition: The Car class defines three properties (attributes) of a car: color, model,
and year.
• Constructor: A constructor method is used to initialize objects of the class. When a Car object
is created, it initializes color, model, and year with specified values.
• Method: The displayDetails() method is defined to print the details of the car.
The four foundational concepts of OOP are Encapsulation, Inheritance, Polymorphism, and
Abstraction. Let’s dive into each with detailed examples.
1. Encapsulation
Encapsulation is the process of combining data and functions that operate on that data within a
single unit, the class. It also restricts direct access to some components, which is critical for
protecting the integrity of data and limiting the scope of code.
In this example, balance is private, so it cannot be directly accessed from outside the class.
We use the public methods getBalance() and deposit() to access and update balance,
ensuring controlled modification.
2. Inheritance
Inheritance is a mechanism by which a new class, called the subclass, inherits the attributes
and behaviors (methods) of an existing class, called the superclass. This promotes code reuse
and allows us to establish a hierarchical relationship between classes.
Benefits of Inheritance
• Code Reusability: Subclasses can reuse methods and attributes of their superclasses, reducing
redundancy.
• Extensibility: We can add new features to existing classes by creating subclasses.
// Subclass
class Dog extends Animal {
// Method overriding
@Override
void makeSound() {
System.out.println("Dog barks");
}
}
In this example:
3. Polymorphism
• Method Overloading: When multiple methods in the same class have the same name but
different parameters.
• Method Overriding: When a subclass provides its specific implementation of a method that is
already defined in its superclass.
4. Abstraction
Abstraction simplifies complex systems by hiding unnecessary details and exposing only
essential features. In Java, abstraction can be implemented using abstract classes and interfaces.
Example: Abstraction in Java
// Abstract class
abstract class Vehicle {
abstract void start(); // Abstract method
}
In this example:
Allows a class to inherit properties and methods from Dog inherits from
Inheritance
another class Animal
Hides implementation details and only exposes essential Abstract Vehicle with
Abstraction
features to the user Car class
By understanding these foundational principles, students can better grasp OOP’s advantages,
such as modularity, ease of maintenance, code reuse, and real-world modeling, which are
essential in developing scalable applications.
3.1 Java
Java is a widely used, high-level, object-oriented programming language known for its
portability, robustness, and rich standard library. It is often chosen for large-scale applications
due to its secure, multithreaded, and memory-managed environment.
• Platform Independence: Java is "write once, run anywhere" (WORA) due to its Java Virtual
Machine (JVM), which allows Java programs to run on any device or operating system.
• Automatic Garbage Collection: Java automatically manages memory, reducing memory leaks
and optimizing memory usage.
• Rich Standard Library: Java provides a wide range of built-in libraries for handling data
structures, input/output operations, and networking.
• Strong Community and Frameworks: Java has a robust ecosystem with frameworks like Spring
and Hibernate, making it highly suitable for enterprise-level applications.
In Java, classes and objects encapsulate data and behavior. Java also supports inheritance,
polymorphism, and interfaces, which are essential for code reuse and flexibility.
Animal(String name) {
this.name = name;
}
void makeSound() {
System.out.println("Animal makes a sound");
}
}
@Override
void makeSound() {
System.out.println(name + " barks");
}
}
3.2 C++
C++ is a powerful language that combines low-level programming capabilities with high-level
OOP features. Known for its efficiency and control over system resources, C++ is often used
in game development, systems programming, and performance-critical applications.
C++ implements classes, inheritance, and polymorphism similarly to Java, but it also includes
unique features like pointers and destructors for memory management.
#include <iostream>
using namespace std;
// Base class
class Animal {
public:
string name;
Animal(string n) : name(n) {}
// Derived class
class Dog : public Animal {
public:
Dog(string n) : Animal(n) {}
int main() {
Animal* animal = new Dog("Buddy");
animal->makeSound(); // Output: Buddy barks
delete animal;
}
In this example:
3.3 Python
Python is a versatile, high-level language that is known for its readability and simplicity.
Though not purely object-oriented, Python supports OOP and provides a straightforward
syntax that makes it popular in web development, data science, artificial intelligence, and
automation.
• Easy Syntax and Readability: Python’s syntax is simple and close to natural language, making
it easy to learn and write.
• Dynamic Typing: Python does not require explicit type declaration, as it infers types at
runtime.
• Rich Ecosystem: Python has extensive libraries for a wide range of applications, including
NumPy for scientific computing and Django for web development.
• Cross-Platform Compatibility: Python code can run on multiple operating systems without
modification.
Python supports classes, inheritance, and polymorphism but with fewer constraints, allowing
for a more flexible approach to OOP.
def make_sound(self):
print("Animal makes a sound")
In this example:
Compiled to machine
Compilation Compiled to bytecode (JVM) Interpreted
code
Platform
Yes (JVM) No Yes
Independence
Complex (low-level
Syntax Complexity Moderate Simple
control)