Unit – V
Syllabus:
UNIT-V Structures, Unions, Bit Fields: Introduction, Nested Structures, Arrays of
Structures, Structures and Functions, Self-Referential Structures, Unions, Enumerated Data
Type —Enum variables, Using Typedef keyword, Bit Fields.
Data Files: Introduction to Files, Using Files in C, Reading from Text Files, Writing to Text
Files, Random File Access.
Knowledge Concepts:
1. Structure Declaration, accessing structure variables
2. Nested Structures and Arrays of Structures
3. Structures and Functions
4. Self-Referential Structures
5. Unions and Enumerated Data Types (Enum)
6. Typedef and Bit Fields
7. Introduction to Files and its modes
8. File Input and Output Operations
9. Random File Access Functions
1. Structure Declaration, accessing structure variables
In C programming, a structure is a user-defined data type that allows the bundling of different
types of data under a single name. It enables the programmer to group variables of various data
types together into a single unit.
The structure declaration defines a blueprint for the structure, specifying the various members
or fields it will contain. It doesn't allocate memory, but it defines a template for how the
memory should be laid out when an actual instance of that structure is created.
Here's the syntax for defining a structure in C:
struct structureName {
dataType1 member1;
dataType2 member2; // ... (additional members)
};
struct: Keyword used to define a structure.
structureName: Name given to the structure. This is used to declare variables of this
structure type.
dataType1, dataType2, etc.: Data types of the members within the structure.
member1, member2, etc.: Names of the members within the structure.
Once the structure is defined, you can declare variables of that structure type, which creates
instances of the structure:
struct structureName variableName;
Then, you can access the members of the structure using the dot operator (.):
variableName.member1 = value1;
variableName.member2 = value2;
Structures are widely used in C for organizing and manipulating complex data structures,
allowing for the representation of real-world entities with multiple attributes and properties
within a program.
Accessing a structure variable:
Accessing structure variables in C involves using the dot (.) operator to access individual
members within the structure.
Example:
Consider a structure representing a person with name and age:
#include <stdio.h>
// Define a structure for a person
struct Person {
char name[50];
int age;
};
int main() {
// Declare a structure variable
struct Person person1; // Accessing structure members and assigning values
strcpy(person1.name, "Alice"); // Using strcpy to copy a string to name
person1.age = 25; // Displaying structure members
printf("Name: %s\n", person1.name);
printf("Age: %d\n", person1.age); return 0;
}
In the example above:
person1.name accesses the name member of the person1 structure.
person1.age accesses the age member of the person1 structure.
The dot operator (.) is used to access and modify the individual members of the
structure.
Nested Structure:
A nested structure in C refers to a structure that is a member of another structure. It involves
defining a structure within another structure, allowing for a hierarchical organization of data.
Example:
#include <stdio.h>
// Outer structure containing an inner structure
struct Outer {
int outerData;
// Inner structure as a member of the outer structure
struct Inner {
int innerData;
} innerStruct; // Inner structure variable
};
int main() {
// Declare an instance of the outer structure
struct Outer outerObj;
// Accessing and assigning values to the outer structure's member
outerObj.outerData = 10;
// Accessing and assigning values to the inner structure's member
outerObj.innerStruct.innerData = 20;
// Displaying values
printf("Outer Data: %d\n", outerObj.outerData);
printf("Inner Data: %d\n", outerObj.innerStruct.innerData);
return 0;
}
In this example:
struct Inner is defined inside struct Outer, making it a nested structure.
struct Inner is a member of struct Outer and is accessed using the dot operator (.)
through an instance of struct Outer.
outerObj is an instance of the outer structure (struct Outer), containing an inner
structure (struct Inner) within it.
Nested structures allow for a more complex organization of data. In this example, struct Inner
is encapsulated within struct Outer, providing a hierarchical structure. This can represent
scenarios where an outer structure contains another structure as part of its data, making the
code more organized and modular.
Array of Structures:
An array of structures in C involves creating an array where each element of the array is a
structure. This allows you to store multiple instances of the same structure type within an array.
Definition:
An array of structures is a collection of multiple structures of the same type, where each
element of the array is a structure instance.
Syntax:
struct StructureName {
// Members of the structure
int member1;
char member2;
// ...
};
// Declaring an array of structures
struct StructureName arrayName[SIZE]; // SIZE represents the number of elements in the array
Example:
Create an array of structures to represent multiple students:
#include <stdio.h>
// Structure to represent a student
struct Student {
int id;
char name[50];
};
int main() {
// Declare an array of structures (students)
struct Student students[3]; // Array of 3 students
// Assigning values to elements of the array
students[0].id = 101;
strcpy(students[0].name, "Alice");
students[1].id = 102;
strcpy(students[1].name, "Bob");
students[2].id = 103;
strcpy(students[2].name, "Charlie");
// Displaying information of students
for (int i = 0; i < 3; ++i) {
printf("Student %d - ID: %d, Name: %s\n", i + 1, students[i].id, students[i].name);
}
return 0;
}
In this example:
struct Student defines the structure for a student with an id and name.
students is an array of struct Student containing three elements.
Each element of the array (students[0], students[1], students[2]) is a struct Student.
Values are assigned to the elements of the array using the dot operator (.) to access
structure members.
The for loop iterates through the array, displaying information about each student.
This demonstrates the concept of an array of structures, allowing you to store and manage
multiple instances of a structure type, such as multiple students in this example.
Differences between a structure and an array variable:
Aspect
Structure Variable
Array Variable
Definition
User-defined composite data type
bundling different types of data into a
single unit.
struct structureName { dataType
member1; dataType member2; ... };
Accessed using dot (.) operator:
variableName.memberName
Memory is allocated separately for each
member.
Collection of elements of the
same data type indexed by
sequential integers.
dataType arrayName[size];
Declaration
Syntax
Accessing
Elements
Memory
Allocation
Element Types Can contain different data types within a
structure.
Grouping Data Groups related data under a single name
(structure).
Flexibility
Allows for a mixture of data types within
a structure.
Size
Size depends on the sum of sizes of
Determination individual members.
Initialization
Iteration
Individual members can be initialized
separately.
Not typically used for sequential access;
elements accessed by name.
Accessed
by
index:
arrayName[index]
Contiguous block of memory
allocated for elements based on
size and data type.
Contains elements of the same
data type in an array.
Stores homogeneous elements
sequentially (array).
Contains elements of a single
type, less flexible.
Size determined by the number
of elements multiplied by the
size of each element.
Elements can be initialized
collectively or individually.
Loops commonly used for
sequential access to elements
by index.
Usage
Scenario
Ideal for representing complex entities Suitable for storing a collection
with multiple attributes/properties.
of similar data elements.
Both structures and arrays serve distinct purposes in programming and are utilized based on
the specific requirements of a given problem or data organization needs. Structures are
employed to group diverse data types into a single unit, while arrays excel at storing a collection
of elements of the same type.
Passing a structure to a function:
Structures can be passed to functions in C either by passing them directly or by passing pointers
to structures. Both methods allow the function to modify the structure's contents.
Passing Structure Directly:
You can pass a structure directly to a function, either by passing it as an argument or by
returning it from a function.
Example - Passing Structure as an Argument:
#include <stdio.h>
// Structure definition
struct Rectangle {
int length;
int width;
};
// Function that takes a structure as an argument
void displayRectangle(struct Rectangle rect) {
printf("Length: %d, Width: %d\n", rect.length, rect.width);
}
int main() {
// Creating a structure variable
struct Rectangle myRect = {5, 10};
// Passing structure to the function
displayRectangle(myRect);
return 0;
}
Passing Structure Pointers:
Passing a pointer to a structure allows the function to directly modify the original structure's
contents.
Example - Passing Structure Pointer as an Argument:
#include <stdio.h>
// Structure definition
struct Point {
int x;
int y;
};
// Function that takes a pointer to a structure as an argument
void modifyPoint(struct Point *p) {
p->x = 15;
p->y = 20;
}
int main() {
// Creating a structure variable
struct Point myPoint = {5, 10};
// Passing a pointer to the structure to the function
modifyPoint(&myPoint);
// Accessing modified values
printf("Modified Point - X: %d, Y: %d\n", myPoint.x, myPoint.y);
return 0;
}
Syntax Summary:
Passing Structure Directly:
void functionName(struct StructureName param) {
// Function body
}
Passing Structure Pointer:
void functionName(struct StructureName *param) {
// Function body
}
Both methods enable functions to manipulate structure members directly, allowing for more
efficient handling of structure data within the program. The choice between passing the
structure directly or using pointers depends on the specific needs and design of the program.
Differences of Passing
Passing a structure to Function:
Memory Handling: When a structure is passed to a function, it's usually passed by
value or by reference.
By Value: A copy of the entire structure is passed to the function. Any
modifications made within the function won't affect the original structure.
By Reference (Pointer): Passing a pointer to the structure allows modifications
within the function to directly affect the original structure outside the function.
This is useful for altering the structure itself.
Manipulation: Functions receiving a structure as an argument can perform operations
directly on the structure's members.
Passing an Array to a Function:
Memory Handling: Arrays in C are generally passed to functions by reference,
effectively passing a pointer to the array's first element.
Array Size: The size of the array needs to be explicitly specified or passed
separately since arrays decay into pointers when passed to functions.
Manipulation: Functions receiving an array can perform operations on the array's
elements. Modifications can directly affect the original array.
Passing a structure Vs passing an array
Aspect
Passing a Structure
Passing an Array
Pass by Value
function(structure variable);
function(arrayName);
Pass by
Reference
Memory
Overhead
Modification in
Function
function(&structure variable);
function(int arr[]); or
function(arr[], size);
No additional memory for the array
itself, only the reference is passed
Modifications made to the array
elements inside the function affect
the original array
Often involves passing just the array
name or array name with size
explicitly
Syntax
Memory Management:
Passing a structure may involve copying the entire structure, potentially
consuming more memory, while arrays often pass references to their first
elements, causing less memory overhead.
Modification of Data:
Extra memory required for a copy of
the entire structure
Changes typically don't affect the
original structure unless passed by
reference using pointers
Requires passing the entire structure
variable
Passing structures by value or arrays without explicit size generally doesn't
directly modify the original data. Passing by reference allows modifications
within functions that affect the original data.
Syntax:
Passing structures involves passing the entire structure variable, while passing
arrays often involves just passing the array name or array name with size
explicitly.
Self-referential Structures:
Self-referential structures in C are structures that contain a pointer member pointing to another
instance of the same structure type. This self-referencing capability allows structures to
reference or contain elements of the same type within themselves.
Definition:
A self-referential structure refers to a structure that contains a member that is a pointer to the
same structure type. This enables a structure to reference or contain instances of its own type.
Uses:
1. Linked Lists: Self-referential structures are commonly used in linked lists, where each
node contains a pointer to the next node of the same type.
2. Trees: In tree data structures, nodes often reference child nodes of the same type.
3. Graphs: For representing graph structures, where nodes might reference other nodes.
4. Recursive Data Structures: Certain recursive data structures utilize self-referential
structures, like trees and nested hierarchies.
Simple Example:
Creating a singly linked list using self-referential structures.
#include <stdio.h>
// Definition of a self-referential structure (linked list node)
struct Node {
int data;
struct Node *next; // Pointer to the next node of the same type
};
int main() {
// Creating nodes of the linked list
struct Node node1, node2, node3;
node1.data = 10;
node2.data = 20;
node3.data = 30;
// Linking nodes together
node1.next = &node2;
node2.next = &node3;
node3.next = NULL; // Marking the end of the linked list
// Accessing linked nodes
printf("Node 1 Data: %d\n", node1.data);
printf("Node 2 Data: %d\n", node1.next->data);
printf("Node 3 Data: %d\n", node1.next->next->data);
return 0;
}
Differences between Nested and Self-referential Structures:
Aspect
Definition
Self-Referential Structures
Nested Structures
Contains a member that points to Defined within another structure
the same structure type
without containing pointers to
itself
Purpose
Enables referencing or containing Creates
a
hierarchical
instances of its own type, organization of structures, but
commonly used in linked lists, doesn’t reference instances of its
trees, graphs
own type
Example
Linked lists, trees, graphs
Structuring data within a
hierarchy
Pointer to own Contains a pointer member to its Doesn't contain pointers to its own
type
own type
type
Relationship
Contains a member that points to Defined within another structure
between
the same structure type, creating a without creating any linkage
members
linkage
Usage in Data Commonly used in data structures Organizes data in a hierarchical
Structures
requiring self-referencing capability manner within a structure
like linked lists, trees, and graphs
Self-referential structures utilize pointers to reference instances of their own type, facilitating
linked data structures, while nested structures are structures defined within another structure
without containing pointers to themselves, organizing data hierarchically without selfreferencing capability. Both have distinct purposes and uses in organizing and manipulating
data within C programs.
Unions
A union in programming is a user-defined data type that allows different types of data to be
stored in the same memory location. Unlike a structure, where each member has its own
memory space, a union allocates enough memory for its largest member, and all members share
that same memory space.
Syntax to Define a Union in C:
union UnionName { // Members of the union
dataType member1;
dataType member2; // ...
};
Advantages of Unions:
1. Memory Efficiency: Unions conserve memory by allowing different types to share the
same memory location. Only the memory required for the largest member is allocated.
2. Versatility: Unions are useful when storing data of different types in the same memory
space is necessary, such as handling different data representations.
3. Conservation of Memory: Especially helpful in embedded systems or situations where
memory is limited, as they optimize memory usage by allowing different types to share
the same space.
Disadvantages of Unions:
1. Ambiguity in Access: Since all members share the same memory location, changing
the value of one member affects other members. This can lead to unintended
consequences if not used carefully.
2. Limited Simultaneous Usage: Only one member of the union can be used at a time.
Changing the value of one member overrides the values of other members.
3. Type Safety Concerns: Unions can potentially lead to type-related errors or bugs if not
handled correctly, as they allow different types to occupy the same memory space.
Example:
union NumericData {
int intValue;
float floatValue;
char charValue;
};
In this example, the NumericData union can hold an integer, a floating-point number, or a
character. All three members (intValue, floatValue, and charValue) share the same memory
location. Accessing one member might affect the interpretation of the data in another member
due to shared memory.
Unions are powerful constructs but require caution and understanding of their usage due to
their potential for unintended side effects and data interpretation issues. They're primarily
useful when optimizing memory and dealing with situations where different types need to share
memory space.
Differences between Structures and Unions:
Aspect
Structures
Unions
Memory
Allocation
Allocates memory separately for Shares memory
each member
members
Memory Usage
Each member has its own memory
space
Size is the sum of sizes of all
members
Access
individual
members
independently
Modifying one member doesn’t
affect others
Useful for grouping related but
different types of data
Appropriate for holding diverse
data simultaneously
May lead to more memory usage
when different types are stored
Offers type safety as each member
has its own memory
struct Person { char name[20];
int age; };
Size Calculation
Member Access
Member
Modifications
Versatility
Use Cases
Memory
Efficiency
Safety
Consideration
Example
among
all
All members share the same
memory space
Size is the size of the largest
member
All members share the same
memory, accessed one at a time
Changing one member affects
other members
Suitable for scenarios where only
one type of data is used at a time
Ideal when only one piece of data
needs to be accessed at a time
Offers memory efficiency by
sharing memory among members
Requires careful handling due to
shared memory among members
union Data { int intValue; float
floatValue; };
enum
An enum in C is a user-defined data type used to define a set of named integral constants,
making the code more readable and manageable by assigning meaningful names to numeric
values.
Definition:
enum (enumeration) in C is a user-defined data type that allows the programmer to define a
list of named constants, where each constant is assigned an integer value by default.
Syntax:
enum enum_name {
constant1,
constant2,
constant3,
// ...
};
Uses:
Creating Named Constants: Enums are useful for creating named constants, making the
code more readable and understandable.
Improving Code Clarity: Enums provide descriptive names to numeric values, making
the code easier to maintain and understand.
Example:
#include <stdio.h>
// Declaration of enum representing days of the week
enum Days {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
};
int main() {
// Using enum constants
enum Days today = TUESDAY;
// Switch statement using enum
switch (today) {
case SUNDAY:
printf("It's Sunday!\n");
break;
case MONDAY:
printf("It's Monday!\n");
break;
case TUESDAY:
printf("It's Tuesday!\n");
break;
// ... other cases for remaining days
default:
printf("Invalid day!\n");
}
return 0;
}
In this example:
enum Days defines an enum type containing days of the week as constants.
Constants like SUNDAY, MONDAY, etc., are implicitly assigned integer values
starting from 0 (SUNDAY) to 6 (SATURDAY) by default.
An enum variable today is declared and initialized with the TUESDAY constant.
A switch statement demonstrates how enums can be used in branching logic based on
the current day.
Enums help improve code readability by giving meaningful names to numeric constants,
enhancing code comprehension and maintenance.
Typedef
typedef in C is a keyword used to create an alias or a new name for existing data types,
including primitive types, structures, or user-defined types. It enhances code readability,
portability, and abstraction by providing alternative names for existing data types.
Definition:
typedef is a C keyword that allows users to create aliases or alternative names for existing data
types, making code more readable and understandable.
Purpose:
Creating Aliases: It provides a way to create shorter, more descriptive names for
existing data types, making the code more readable and maintainable.
Enhancing Portability: typedef can help improve code portability by defining custom
names for data types, abstracting away implementation details.
Syntax:
typedef existing_type new_type_name;
Example:
#include <stdio.h>
// Defining a new type using typedef
typedef int Length;
int main() {
Length distance = 10; // Using the new type
printf("Distance: %d\n", distance);
return 0;
}
In this example:
typedef int Length; creates a new type named Length, which is an alias for the int
data type.
Length distance = 10; declares a variable distance of type Length, which is essentially
an int.
Additional Use Cases:
Struct Typedefs: Creating aliases for complex or nested structures to simplify their
usage.
Function Pointers: Simplifying the syntax for function pointers for better code
readability.
Portability: Using typedefs to create code that is easier to port across different
platforms by abstracting away underlying data types.
typedef provides a way to improve code readability and maintainability by giving more
descriptive names to data types, thereby making the code more self-explanatory and easier to
understand.
Bitfields
Bitfields in C are a way to specify and manipulate the individual bits within a single storage
unit (like a byte) rather than dealing with entire bytes or words. They allow the allocation of
specified numbers of bits to represent data fields within a structure or union.
Definition:
Bitfields in C are used to specify the number of bits to be used for each member within a
structure or union, allowing more efficient use of memory by packing data tightly.
Syntax:
struct BitField {
datatype member1 : width1;
datatype member2 : width2;
// ...
};
datatype represents the data type of the bitfield member.
width represents the number of bits allocated to the member.
Uses:
Memory Optimization: Bitfields allow the efficient use of memory by packing
multiple bitfields into a single storage unit.
Flags or Boolean Variables: They are commonly used to represent flags or boolean
variables, where each bit can represent a true/false or on/off state.
Operations Not Supported on Bitfields:
Address of Operator (&): The address of a bitfield member cannot be obtained.
Size of Operator (sizeof): sizeof operator might not give the size of the bitfield as
expected due to padding by the compiler.
Direct Initialization: Bitfields cannot be directly initialized within a structure.
Advantages:
Memory Efficiency: Bitfields allow efficient use of memory by packing data tightly.
Enhanced Readability: They enhance code readability by representing multiple flags
or variables in a single unit.
Disadvantages:
Platform Dependence: The behavior of bitfields might vary between different
compilers and architectures.
Portability Concerns: Code using bitfields might not be portable across different
systems.
Complicated Syntax: Handling bitfields might require more complex code and
understanding of bitwise operations.
Simple Example:
#include<stdio.h>
struct date {
unsigned int day;
unsigned int month;
unsigned int year;
};
struct date2 {
unsigned short int day:5;
unsigned short int month:4;
unsigned short int year:8;
};
void main() {
struct date dob = {10, 12, 94};
struct date2 doj = { 30, 1, 23};
printf("Date of Birth using dob = %u/%u/%u\n", dob.day, dob.month, dob.year);
printf("Date of Join using doj = %u/%u/%u\n", doj.day, doj.month, doj.year);
printf("Size of dob using structure = %d\n", sizeof(dob));
printf("Size of doj using bit fields = %d\n", sizeof(doj));
}
Sample programs on Structures:
Write a C Program to add two complex numbers using structures.
#include <stdio.h>
// Define a structure to represent a complex number
struct complex {
float real;
float imaginary;
};
// Function to add two complex numbers
struct complex add_complex(struct complex num1, struct complex num2) {
struct complex result;
// Adding real parts and imaginary parts separately
result.real = num1.real + num2.real;
result.imaginary = num1.imaginary + num2.imaginary;
return result;
}
int main() {
struct complex complex1, complex2, sum;
// Input for first complex number
printf("Enter real and imaginary parts of first complex number:\n");
printf("Real Part: ");
scanf("%f", &complex1.real);
printf("Imaginary Part: ");
scanf("%f", &complex1.imaginary);
// Input for second complex number
printf("\nEnter real and imaginary parts of second complex number:\n");
printf("Real Part: ");
scanf("%f", &complex2.real);
printf("Imaginary Part: ");
scanf("%f", &complex2.imaginary);
// Calculate the sum of complex numbers
sum = add_complex(complex1, complex2);
// Display the result
printf("\nSum: %.2f + %.2fi\n", sum.real, sum.imaginary);
return 0;
}
Files
In C, the FILE data structure is used to handle files. It's a structure defined in the standard
input/output library (stdio.h) that holds information about a file being accessed or manipulated.
The FILE structure provides a way to interact with files through various functions like fopen,
fclose, fread, fwrite, etc.
FILE Structure:
The FILE structure includes various members that store information about the opened file,
such as file descriptor, file position indicator, end-of-file indicator, error indicator, and more.
Handling Files in C:
Opening Files (fopen): To open a file, you use the fopen function, which returns a
pointer to a FILE structure.
Closing Files (fclose): After performing file operations, it's crucial to close the file
using fclose to release resources associated with the file.
Reading/Writing Files (fread, fwrite): These functions allow reading from or writing
to files using the FILE pointer.
Moving File Pointer (fseek, ftell): Functions like fseek and ftell allow you to set the
file position indicator and obtain the current position in the file, respectively.
Error Handling (ferror, feof): Functions such as ferror and feof help in error
checking and end-of-file detection while working with files.
File Modes:
The fopen function takes a file mode parameter that specifies the intended operations on the
file. Here are some common file modes:
"r": Opens a file for reading. The file must exist.
"w": Opens a file for writing. If the file exists, it truncates it. If it doesn’t exist, a new
file is created.
"a": Opens a file for appending. New data is written at the end of the file.
"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 truncates it. If it
doesn’t exist, a new file is created.
Complete list:
Mode
Description
Characteristics
"r"
Read mode
- Opens file for reading.
- File must exist; returns an error if the file doesn't exist.
"w"
Write mode
- File pointer is positioned at the beginning of the file.
- Opens file for writing.
- If the file exists, it's truncated (deleting previous content).
- If the file doesn't exist, it creates a new file.
"a"
Append mode
- File pointer is positioned at the beginning of the file.
- Opens file for writing at the end.
- If the file exists, the file pointer is positioned at the end.
- If the file doesn't exist, it creates a new file.
"r+"
"w+"
Read/Write
mode
Read/Write
mode
- Appends data to the existing content.
- Opens file for both reading and writing.
- File must exist; returns an error if the file doesn't exist.
- File pointer is positioned at the beginning of the file.
- Opens file for both reading and writing.
- If the file exists, it's truncated (deleting previous content).
- If the file doesn't exist, it creates a new file.
"a+"
Read/Append
mode
- File pointer is positioned at the beginning of the file.
- Opens file for both reading and appending.
- If the file exists, the file pointer is positioned at the end.
- If the file doesn't exist, it creates a new file.
"rb"
Read
Binary
mode
"wb"
Write
Binary
mode
"ab"
Append Binary
mode
"r+b" or Read/Write
"rb+"
Binary mode
"w+b"
Read/Write
or
Binary mode
"wb+"
"a+b" or Read/Append
"ab+"
Binary mode
- Appends data to the existing content.
- Opens a binary file for reading in binary mode.
- Opens a binary file for writing in binary mode.
- Opens a binary file for appending in binary mode.
- Opens a binary file for both reading and writing.
- Opens a binary file for both reading and writing.
- Opens a binary file for both reading and appending
Types of Files:
Text files and binary files are two primary ways of storing data in computer systems, each with
its characteristics and usage scenarios:
Text Files:
Representation: Text files store data in a human-readable format using characters from
a defined character set (e.g., ASCII, Unicode).
Contents: They contain plain text, including alphabets, numbers, symbols, and control
characters (newline, tab, etc.).
Structure: Lines of text are delimited by newline characters ('\n' or "\r\n" in different
systems).
Editing: Can be edited using basic text editors (e.g., Notepad, TextEdit).
Examples: .txt, .csv, .html, .xml files are common examples of text files.
Usage: Suitable for storing textual data such as documents, source code, configuration
files, etc.
Size: Text files tend to be larger than their binary counterparts due to storing characters
in their readable form.
Binary Files:
Representation: Binary files store data in a raw binary format, consisting of 0s and 1s,
which can represent any type of data.
Contents: They contain a sequence of bytes without any specific character encoding or
structure.
Structure: The structure is determined by the application and isn't inherently humanreadable.
Editing: Not easily editable using standard text editors due to the lack of readability.
Examples: Executable files, images (JPEG, PNG), audio (MP3), video (MP4),
databases (DB), etc., are binary files.
Usage: Ideal for storing non-textual data or complex data structures where precise
binary representation is essential.
Size: Binary files might be smaller than their text equivalents because they don't need
to represent characters explicitly.
Differences:
Readability: Text files are human-readable, while binary files are not.
Content: Text files contain text characters, while binary files contain raw binary data.
Editing: Text files can be easily edited using text editors, while binary files require
specific software or programs for manipulation.
Size: Text files might be larger due to their human-readable representation compared
to binary files, which store data more compactly.
Text files are suitable for storing human-readable data like documents or code, while binary
files are used for storing non-textual or complex data in a more compact and efficient manner.
File Input/Output Operations:
File Input/Output (I/O) in C refers to the operations performed on files, including reading from
and writing to files. The C standard library provides functions for handling file I/O operations.
Some of the key functions used for file I/O include:
Opening/Closing Files:
fopen(): Opens a file and returns a pointer to a FILE structure.
fclose(): Closes the file associated with a FILE pointer.
Reading from Files:
fgetc(): Reads a single character from a file.
fgets(): Reads a line of text from a file.
fscanf(): Reads formatted data from a file.
fread(): Reads a block of data from a file.
Writing to Files:
fputc(): Writes a single character to a file.
fputs(): Writes a string to a file.
fprintf(): Writes formatted data to a file.
fwrite(): Writes a block of data to a file.
File Positioning/ Random access Functions:
fseek(): Sets the file position indicator within a file.
ftell(): Returns the current file position indicator's position.
rewind(): Sets the file position indicator to the beginning of the file.
Error Handling:
feof(): Checks for the end-of-file indicator for a file.
ferror(): Checks for file I/O errors.
File Operations:
remove(): Deletes a file.
Example:
rename(): Renames a file.
tmpfile(): Creates a temporary file.
These functions are part of the standard C library (stdio.h) and are used for performing various
operations related to file I/O, such as opening, reading, writing, positioning within files,
handling errors, and performing file-related operations like deletion or renaming. They
manipulate the FILE type provided by the library, allowing interaction with files in C
programs.
Opening/Closing Files:
fopen() Function:
Description: fopen() is a function used to open a file and associates it with a FILE
stream, returning a pointer to a FILE structure.
Purpose: It's used to access files for reading, writing, or appending data within a C
program.
Syntax:
FILE *fopen(const char *filename, const char *mode);
filename: A string representing the name of the file to be opened.
mode: A string representing the mode in which the file is to be opened ("r",
"w", "a", "r+", "w+", "a+", "rb", "wb", etc.).
Return Values:
Returns a pointer to a FILE structure if the file is successfully opened.
Returns NULL if the file cannot be opened or an error occurs.
Example:
FILE *filePtr;
filePtr = fopen("example.txt", "r"); // Opens a file named example.txt for reading
if (filePtr == NULL) {
printf("File failed to open.");
} else {
printf("File opened successfully.");
fclose(filePtr); // Close the file after use
}
fclose() Function:
Description: fclose() is a function used to close the file associated with a FILE pointer,
flushing any buffered output.
Purpose: It's used to release resources associated with the file and close the file stream.
Syntax:
int fclose(FILE *stream);
stream: A pointer to a FILE structure representing the file stream to be closed.
Return Values:
Returns 0 on successful closing of the file.
Returns EOF (End-of-File) if an error occurs while closing the file.
Example:
FILE *filePtr;
filePtr = fopen("example.txt", "r");
if (filePtr != NULL) {
// Perform operations with the file
fclose(filePtr); // Close the file when done
printf("File closed successfully.");
} else {
printf("File failed to open.");
}
These functions (fopen() and fclose()) are fundamental for handling file operations in C.
fopen() is used to open files for various purposes, and fclose() is used to safely close the files
once their operations are complete to release system resources. Always remember to check if
the file opened successfully before performing operations and close the file after use to prevent
resource leaks.
fgetc() function:
Description: fgetc() reads a single character from a file associated with a FILE
pointer.
Use: Used to read individual characters from a file.
Syntax:
int fgetc(FILE *stream);
stream: A pointer to a FILE structure representing the file to be read.
Return Value:
Returns the character read as an int value (cast to char if required).
Returns EOF (End-of-File) if the end of the file is reached or an error occurs.
Example:
FILE *filePtr;
int ch;
filePtr = fopen("example.txt", "r");
if (filePtr != NULL) {
ch = fgetc(filePtr); // Reads a character from the file
printf("Character read: %c\n", (char)ch);
fclose(filePtr);
} else {
printf("File failed to open.");
}
fputc() Function:
Description: fputc() writes a single character to a file associated with a FILE pointer.
Use: Used to write individual characters to a file.
Syntax:
int fputc(int c, FILE *stream);
c: The character to be written, provided as an int (converted to unsigned char).
stream: A pointer to a FILE structure representing the file to be written.
Return Value:
Returns the character written as an unsigned char cast to an int.
Returns EOF if an error occurs.
Example:
FILE *filePtr;
char ch = 'A';
filePtr = fopen("output.txt", "w");
if (filePtr != NULL) {
fputc(ch, filePtr); // Writes a character to the file
fclose(filePtr);
printf("Character written successfully.");
} else {
printf("File failed to open.");
}
Write a C program to write contents into a file and display the file content on screen.
#include<stdio.h>
void main() {
FILE *fp;
char ch, filename[30];
printf("Enter file name: ");
scanf("%s", filename);
fp=fopen(filename,"w");
if (fp == NULL) {
printf("Error opening the file.\n");
return 1;
}
printf("Enter text to enter. ctr+d to close: ");
while((ch=getchar())!=EOF){
fputc(ch,fp);
}
fclose(fp);
printf("File contents are: \n");
fp=fopen(filename, "r");
fp=fopen(filename,"w");
if (fp == NULL) {
printf("Error opening the file.\n");
return 1;
}
while((ch=fgetc(fp))!=EOF){
putchar(ch);
}
fclose(fp);
}
fgets() Function:
Description: fgets() reads a line of text from a file associated with a FILE pointer.
Use: Used to read a line of text from a file, including newline characters if present.
Syntax:
char *fgets(char *str, int n, FILE *stream);
str: Pointer to a character array where the line will be stored.
n: Maximum number of characters to read (buffer size).
stream: A pointer to a FILE structure representing the file to be read.
Return Value:
Returns a pointer to the read string (str) on success.
Returns NULL if an error occurs or if the end of the file is reached.
Example:
FILE *filePtr;
char buffer[100];
filePtr = fopen("example.txt", "r");
if (filePtr != NULL) {
fgets(buffer, sizeof(buffer), filePtr); // Reads a line from the file
printf("Line read: %s\n", buffer);
fclose(filePtr);
} else {
printf("File failed to open.");
}
fputs() Function:
Description: fputs() writes a string to a file associated with a FILE pointer.
Use: Used to write a string to a file.
Syntax:
int fputs(const char *str, FILE *stream);
str: Pointer to the null-terminated string to be written.
stream: A pointer to a FILE structure representing the file to be written.
Return Value:
Returns a non-negative value on success.
Returns EOF if an error occurs.
Example:
FILE *filePtr;
const char *text = "Hello, World!";
filePtr = fopen("output.txt", "w");
if (filePtr != NULL) {
fputs(text, filePtr); // Writes a string to the file
fclose(filePtr);
printf("String written successfully.");
} else {
printf("File failed to open.");
}
Sample Program using fgets() and fputs() functions:
#include <stdio.h>
#define MAX_SIZE 1000 // Maximum characters to read
int main() {
FILE *fp;
char data[MAX_SIZE];
// Open file in write mode
fp = fopen("output.txt", "w");
if (fp == NULL) {
printf("File open error\n");
return 1;
}
printf("Enter data to write to the file (Press Ctrl + D to end on UNIX systems or Ctrl +
Z on Windows to terminate):\n");
// Read data from keyboard and write to file using fputs
while (fgets(data, MAX_SIZE, stdin) != NULL) {
fputs(data, fp);
}
// Close the file
fclose(fp);
printf("Data written to file successfully.\n");
return 0;
}
fscanf() Function:
Description: fscanf() reads formatted data from a file associated with a FILE
pointer.
Use: Used to read data from a file according to a specified format.
Syntax:
int fscanf(FILE *stream, const char *format, ...);
stream: A pointer to a FILE structure representing the file to be read.
format: String containing format specifiers to read data.
Return Value:
Returns the number of input items successfully matched and assigned.
Returns EOF if the end of the file is reached or an error occurs.
Example:
FILE *filePtr;
int num1, num2;
filePtr = fopen("numbers.txt", "r");
if (filePtr != NULL) {
fscanf(filePtr, "%d %d", &num1, &num2); // Reads two integers from the file
printf("Numbers read: %d, %d\n", num1, num2);
fclose(filePtr);
} else {
printf("File failed to open.");
}
fprintf() Function:
Description: fprintf() writes formatted data to a file associated with a FILE pointer.
Use: Used to write data to a file according to specified formats.
Syntax:
int fprintf(FILE *stream, const char *format, ...);
stream: A pointer to a FILE structure representing the file to be written.
format: String containing format specifiers to write data.
Return Value:
Returns the number of characters written on success.
Returns a negative value if an error occurs.
Example:
FILE *filePtr;
int num1 = 10, num2 = 20;
filePtr = fopen("output.txt", "w");
if (filePtr != NULL) {
fprintf(filePtr, "Numbers: %d, %d\n", num1, num2); // Writes formatted data to the
file
fclose(filePtr);
printf("Formatted data written successfully.");
} else {
printf("File failed to open.");
}
fread() Function:
Description: fread() reads a block of data from a file associated with a FILE pointer.
Use: Used to read a specific number of bytes from a file.
Syntax:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr: Pointer to the buffer where the data will be stored.
size: Size in bytes of each element to be read.
nmemb: Number of elements to be read.
stream: A pointer to a FILE structure representing the file to be read.
Return Value:
Returns the number of elements read successfully.
Returns an error value if an error occurs.
Example:
FILE *filePtr;
char buffer[100];
filePtr = fopen("binary_data.bin", "rb");
if (filePtr != NULL) {
fread(buffer, sizeof(char), sizeof(buffer), filePtr); // Reads a block of data
// Process or use the read data
fclose(filePtr);
} else {
printf("File failed to open.");
}
fwrite() Function:
Description: fwrite() writes a block of data to a file associated with a FILE pointer.
Use: Used to write a specified number of bytes from a memory buffer to a file.
Syntax:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr: Pointer to the data to be written.
size: Size in bytes of each element to be written.
nmemb: Number of elements to be written.
stream: A pointer to a FILE structure representing the file to be written.
Return Value:
Returns the number of elements successfully written.
Returns an error value if an error occurs.
Example:
FILE *filePtr;
char buffer[] = "Data to be written.";
filePtr = fopen("data.bin", "wb");
if (filePtr != NULL) {
fwrite(buffer, sizeof(char), sizeof(buffer), filePtr); // Writes a block of data to the file
fclose(filePtr);
printf("Data written successfully.");
} else {
printf("File failed to open.");
}
Random Access Functions:
Random access functions allow you to manipulate the file position indicator within a file. They
include fseek(), ftell(), and rewind().
fseek():
Purpose: fseek() sets the file position indicator for the specified file stream.
Syntax:
int fseek(FILE *stream, long int offset, int origin);
stream: Pointer to the file.
offset: Number of bytes to offset from the origin.
origin: Starting point for the offset (SEEK_SET, SEEK_CUR, or SEEK_END).
Return Value: It returns zero on success and a non-zero value on failure.
Description: fseek() repositions the file pointer to the specified position within the file stream.
Example:
FILE *fp;
fp = fopen("example.txt", "r");
fseek(fp, 10, SEEK_SET); // Move the pointer to the 10th byte from the beginning
ftell():
Purpose: ftell() returns the current position of the file pointer within a file.
Syntax:
long int ftell(FILE *stream);
stream: Pointer to the file.
Return Value: It returns the current position indicator of the file stream.
Example:
FILE *fp;
long int position;
fp = fopen("example.txt", "r");
fseek(fp, 10, SEEK_SET); // Move the pointer to the 10th byte from the beginning
position = ftell(fp); // Get the current position
Differences between fseek() and ftell():
Function fseek()
Purpose
Sets the file position indicator
within a file.
Syntax
int fseek(FILE *stream, long
offset, int whence);
Parameters
stream: Pointer to the FILE
object
offset: Number of bytes to offset
whence: Starting point for the
offset
Return Value
Returns 0 upon successful
repositioning
Returns non-zero value on
failure
Whence
ftell()
Returns the current file position
indicator's position.
long ftell(FILE *stream);
stream: Pointer to the FILE object
Returns
the
current
position
indicator's position in the file.
On failure, returns -1L (long integer
value -1) or another implementationspecific value.
SEEK_SET: Beginning of the file (offset bytes from the
beginning)
SEEK_CUR: Current position indicator
SEEK_END: End of the file
-
Usage
Used to move the file pointer
within a file
fseek(fp, 10L, SEEK_SET); //
Move 10 bytes from the
beginning
fseek(fp, -10L, SEEK_CUR); //
Move 10 bytes backward from
current position
fseek(fp, 0L, SEEK_END); //
Move to the end of the file
Example
Used to determine the current
position of the file pointer
long pos = ftell(fp); // Get current
position
-
rewind():
Purpose: rewind() sets the file position indicator to the beginning of the file.
Syntax:
void rewind(FILE *stream);
stream: Pointer to the file.
Return Value: It returns nothing (void).
Example:
FILE *fp;
fp = fopen("example.txt", "r");
rewind(fp); // Reset file pointer to the beginning of the file
Error Handling Functions:
feof():
Description: feof() checks for the end-of-file (EOF) indicator for a file. It returns a
non-zero value if the end-of-file indicator associated with the file has been set after an
operation like reading past the end of the file.
Syntax:
int feof(FILE *stream);
stream: Pointer to the file.
Use: Typically, feof() is used after reading from a file to determine if the end of the file
has been reached.
Return Value: It returns a non-zero value if the end-of-file indicator is set; otherwise,
it returns zero.
stream: Pointer to the file.
Use: Typically, feof() is used after reading from a file to determine if the end of the file
has been reached.
Return Value: It returns a non-zero value if the end-of-file indicator is set; otherwise,
it returns zero.
Example:
FILE *fp;
char ch;
fp = fopen("example.txt", "r");
while (!feof(fp)) {
ch = fgetc(fp);
if (feof(fp)) {
printf("End of file reached.\n");
break;
}
// Process 'ch'
}
fclose(fp);
Error Handling Functions:
feof():
Description: feof() checks for the end-of-file (EOF) indicator for a file. It returns a
non-zero value if the end-of-file indicator associated with the file has been set after an
operation like reading past the end of the file.
Syntax:
int feof(FILE *stream);
stream: Pointer to the file.
Use: Typically, feof() is used after reading from a file to determine if the end of the file
has been reached.
Return Value: It returns a non-zero value if the end-of-file indicator is set; otherwise,
it returns zero.
stream: Pointer to the file.
Use: Typically, feof() is used after reading from a file to determine if the end of the file
has been reached.
Return Value: It returns a non-zero value if the end-of-file indicator is set; otherwise,
it returns zero.
Example:
FILE *fp;
char ch;
fp = fopen("example.txt", "r");
while (!feof(fp)) {
ch = fgetc(fp);
if (feof(fp)) {
printf("End of file reached.\n");
break;
}
// Process 'ch'
}
fclose(fp);
ferror():
Description: ferror() checks for file I/O errors associated with a file. It checks whether
an error occurred during a file operation, like reading from or writing to a file.
Syntax:
int ferror(FILE *stream);
stream: Pointer to the file.
Use: ferror() is used after file operations to determine if any error occurred.
Return Value: It returns a non-zero value if an error occurred; otherwise, it
returns zero.
Example:
FILE *fp; fp = fopen("example.txt", "r");
if (ferror(fp)) {
printf("Error reading from file.\n");
} else {
printf("No error detected.\n");
}
fclose(fp);
Example Programs:
Write a C program to read and display the contents on the screen.
#include <stdio.h>
int main() {
FILE *filePointer;
char ch;
// Opening a file in read mode
filePointer = fopen("example.txt", "r");
// Checking if file opened successfully
if (filePointer == NULL) {
printf("Unable to open file.\n");
return 1;
}
// Reading and printing contents character by character
while ((ch = fgetc(filePointer)) != EOF) {
printf("%c", ch);
}
// Closing the file
fclose(filePointer);
return 0;
}
Structures Programs:
1. Create an Employee database with eid, emp_name, empsal, doj fields;
2. Build a student database with name, rollno, marks of three subjects. Find the total and
average and display Student details with the help of structures.
3. Create nested structure and show how to access all members with help of a program.
4. Create a C program which shows the differences between structures and unions.
5. Implement bit fields to demonstrate the benefits of it using your own scenario.
6. Create Singly linked list and access all elements using self-referential structures.
7. Create a C Program to add two complex numbers using structures and functions.
Files Programs:
1.
2.
3.
4.
5.
Write a C program to simulate cp command using command line arguments.
Write a C program to display contents from a file.
Write a C program to write contents into a file and display it on screen.
Write a C program to merge two file contents into a third file.
Write a C program to create a student database using structures with details like
Student rollno, name and 3 subject marks.
Write a C program to display a student record based on roll no. search.
Write a C program to print last n characters of a file.
6.
7.
Solutions for the Programs:
1. Create an Employee database with eid, emp_name, empsal, doj fields.
#include<stdio.h>
struct date {
int day;
int month;
int year;
};
struct Employee {
int eid;
char name;
float sal;
struct date doj;
};
#define MAX 20
void main() {
int n;
printf(“Enter No. of employees: ”);
scanf(“%d”, &n);
struct Employee e[n];
for(i = 0; i < n; i++) {
printf(“Employee - %d Details\n”, i+1);
printf(“Enter Employee ID, Name, Salary, Date of Join(dd/mm/yyyy): “);
scanf(“%d %s %f %d/%d/%d”, &e[i].eid, e[i].name, &e[i].sal, &e[i].doj.day,
&e[i].doj.month, &e[i].doj.year);
}
printf(“Employee Details are:\n”);
printf(“EID\t\tEMPNAME\t\tSALARY\t\tDateof Join\n”);
for(i=0; i< n; i++) {
printf(“%d\t\t%s\t\t%f\t\t%d/%d/%d\n”,
e[i].doj.day, e[i].doj.month, e[i].doj.year);
e[i].eid,
e[i].name,
e[i].sal,
}
}
i
i
Compiled by K V Subba Raju
Sr. Asst. Prof. CSE
Commented [SK1]:
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )