File handling is a fundamental skill for any C programmer, enabling programs to interact with persistent data on a computer’s disk for tasks like managing records, storing configurations, and logging activity.
This comprehensive guide presents 25+ C Programming file handling exercises designed to take you from basics to advanced techniques.
Each exercise includes a Practice Problem, Hint, Solution code, and detailed Explanation, ensuring you don’t just copy code, but genuinely understand how and why it works.
What You’ll Practice
The challenges cover the following core topics:
- Basic Text I/O: Reading, writing, and appending text files using fundamental functions like
fopen(),fclose(),fprintf(), andfscanf(). - Character Processing: Character-by-character I/O with
fgetc()andfputc()for tasks like word counting and analysis. - Access Methods: Using
fseek()andftell()for Sequential and Random Access to navigate files and calculate size. - Binary Data: Storing and retrieving complex data structures (structs) in binary format using
fwrite()andfread(). - Error Management: Implementing robust checks for file failures and handling system-level errors with
perror().
+ Table of Contents (26 Exercises)
Table of contents
- Exercise 1: Create and Write to a File
- Exercise 2: Read and Display File Content
- Exercise 3: Append Data to a File
- Exercise 4: Count Characters in a File
- Exercise 5: Count Lines in a File
- Exercise 6: Count Words in a File
- Exercise 7: Copy File
- Exercise 8: Display a Specific Line of a File
- Exercise 9: Write a Series of Numbers to a File
- Exercise 10: Read Numbers and Calculate Sum
- Exercise 11: Uppercase Conversion
- Exercise 12: Remove Vowels from a File
- Exercise 13: Search for a Word
- Exercise 14: Replace Word in a File
- Exercise 15: Display File Content in Reverse
- Exercise 16: Merge Two Files
- Exercise 17: Tab to Spaces Conversion
- Exercise 18: Simple Encryption (Caesar Cipher)
- Exercise 19: Simple Decryption (Caesar Cipher)
- Exercise 20: Write Student Record (Binary)
- Exercise 21: Read Student Record (Binary)
- Exercise 22: Multiple Records (Binary)
- Exercise 23: Search and Display Record (Binary)
- Exercise 24: Update Record (Binary)
- Exercise 25: Determine File Size
- Exercise 26: Robust Error Checking
Exercise 1: Create and Write to a File
Practice Problem: Develop a C program to create a new text file named data.txt and write two lines of personal information (e.g., your name and age) to it using fprintf().
Expected Output:
Data successfully written to data.txt.
data.txt
Name: Alice Johnson
Age: 30 years
+ Hint
Use fopen() with the write mode ("w") to create or overwrite the file. Remember to check if the file pointer is NULL to handle potential errors, and use fclose() when finished.
+ Show Solution
#include <stdio.h>
#include <stdlib.h> // Needed for exit()
int main() {
// Declare a file pointer
FILE *fp;
char name[] = "Alice Johnson";
int age = 30;
// Open the file in write mode ("w")
fp = fopen("data.txt", "w");
// Check for file opening error
if (fp == NULL) {
printf("Error opening file!\n");
// Exit the program if file cannot be opened
exit(1);
}
// Write data to the file
fprintf(fp, "Name: %s\n", name);
fprintf(fp, "Age: %d years\n", age);
// Close the file
fclose(fp);
printf("Data successfully written to data.txt.\n");
return 0;
}Code language: C++ (cpp)
Explanation:
- The program first declares a
FILEpointer,fp. It attempts to opendata.txtin write mode ("w"). If the file doesn’t exist, it’s created; if it exists, its content is truncated (deleted). The program checks iffpisNULL, which indicates a failure to open the file. - If successful,
fprintf()is used exactly likeprintf(), but its first argument is the file pointer, directing the output to the file instead of the console. Finally,fclose(fp)is called to close the file, flushing any remaining buffers and releasing the file resource.
Exercise 2: Read and Display File Content
Practice Problem: Read the entire content of the existing file data.txt (created in Exercise 1) and display it line by line on the console using fscanf() or fgets().
Expected Output:
Name: Alice Johnson
Age: 30 years
+ Hint
Open the file in read mode ("r"). Use a loop with fgets() to read strings line by line until it returns NULL (indicating the End-Of-File, or EOF, is reached).
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
char buffer[100]; // Buffer to hold each line of data
// Open the file in read mode ("r")
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("Error opening file or file not found!\n");
exit(1);
}
printf("Content of data.txt:\n");
printf("---------------------\n");
// Read content line by line using fgets()
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
// Print the line read from the file to the console
printf("%s", buffer);
}
// Close the file
fclose(fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- The file is opened in read mode (
"r"). A character array,buffer, is used as a temporary storage space for each line read. - The
fgets()function reads a line from the file stream (fp) and stores it intobuffer, reading at mostsizeof(buffer) - 1characters, or until a newline character or EOF is encountered. - The loop continues as long as
fgets()returns a non-NULL value. The content of the buffer is then printed to the standard output usingprintf().
Exercise 3: Append Data to a File
Practice Problem: Open the existing file data.txt(created in Exercise 1) in append mode and add today’s date and a short message (“Successfully appended.”) as new lines to the end of the file.
Expected Output:
data.txt
Name: Alice Johnson
Age: 30 years
Date Appended: 2025-10-15
Status: Successfully appended.
+ Hint
Use fopen() with the append mode ("a"). The append mode ensures that any new data is written to the end of the existing file content without overwriting it.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
// Use a simple date string for demonstration
char date[] = "2025-10-15";
// Open the file in append mode ("a")
fp = fopen("data.txt", "a");
if (fp == NULL) {
printf("Error opening file!\n");
exit(1);
}
// Write the new data (appended to the end)
fprintf(fp, "Date Appended: %s\n", date);
fprintf(fp, "Status: Successfully appended.\n");
// Close the file
fclose(fp);
printf("New data successfully appended to data.txt.\n");
return 0;
}Code language: C++ (cpp)
Explanation:
The core difference here is the use of the append mode ("a") in fopen(). When a file is opened in this mode, the file pointer is automatically positioned at the end of the file. Subsequent write operations using fprintf() or other output functions will simply add the new data after the existing content, preserving the original data.
Exercise 4: Count Characters in a File
Practice Problem: Write a program to read a text file (e.g., data.txt updated in Exercise 3) character by character and count the total number of characters in it, including spaces and newlines.
Expected Output:
Total number of characters in the file: 91
+ Hint
Open the file in read mode ("r"). Use a loop with the fgetc() function to read one character at a time. The loop should terminate when fgetc() returns the EOF (End-Of-File) constant.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
int character;
long char_count = 0; // Use long for potentially large files
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("Error: Could not open data.txt\n");
exit(1);
}
// Read the file character by character
while ((character = fgetc(fp)) != EOF) {
char_count++;
}
fclose(fp);
printf("Total number of characters in the file: %ld\n", char_count);
return 0;
}Code language: C++ (cpp)
Explanation:
- The file is read using the
fgetc()function, which returns the next character from the file stream as anint. We use anintto store the return value because it must be able to hold theEOFvalue (which is outside the range of a standardchar). - Inside the
whileloop, as long as the returned value is not equal toEOF, the character counter (char_count) is incremented.
Exercise 5: Count Lines in a File
Practice Problem: Read a any text file (e.g., data.txt updated in Exercise 3) and count the total number of lines in it. (A line is typically counted by the presence of the newline character \n).
Expected Output:
Total number of lines in the file: 4
+ Hint
Similar to the character counting exercise, use fgetc(). Inside the loop, check if the character read is equal to the newline character ('\n'). Increment a counter each time a newline is found.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
int character;
int line_count = 0;
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("Error: Could not open data.txt\n");
exit(1);
}
// Read character by character
while ((character = fgetc(fp)) != EOF) {
// Check for the newline character
if (character == '\n') {
line_count++;
}
}
// A common convention: If the file is not empty and doesn't end with a newline,
// the last line won't have been counted yet. We check the file size to see if it's empty.
if (line_count == 0) {
// Reset pointer to beginning to check if file is empty
fseek(fp, 0, SEEK_END);
if (ftell(fp) > 0) {
line_count = 1; // It's not empty, so it has at least one line
}
} else {
// If there was content and the last character wasn't a newline, increment count
// Simpler approach: Check if the last character read was NOT a newline
fseek(fp, -1, SEEK_END);
if (fgetc(fp) != '\n') {
line_count++;
}
}
// Simpler, more robust approach:
// if (line_count > 0 || (fseek(fp, 0, SEEK_END) != -1 && ftell(fp) > 0) ) {
// // Logic to handle the last line without a newline
// }
fclose(fp);
printf("Total number of lines in the file: %d\n", line_count);
return 0;
}Code language: C++ (cpp)
Explanation:
This exercise uses fgetc() to iterate through the file.
- The program specifically looks for the newline character (
'\n'); every time this character is found, theline_countis incremented. - A key complexity in line counting is handling the last line of the file. If a file ends with actual content but without a final newline character, the last line won’t be counted.
- The robust solution often involves a conditional check after the loop to see if the file contained any characters at all and if the last character read was not a newline.
Exercise 6: Count Words in a File
Practice Problem: Read a any text file (e.g., data.txt updated in Exercise 3) and count the total number of words. Assume words are separated by spaces, tabs, or newlines.
Expected Output:
Total number of words in the file: 12
+ Hint
This is a state-machine problem. Define a state variable (IN or OUT of a word). When you encounter a non-delimiter character and the state is OUT, a new word has started, so increment the word count and change the state to IN.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> // For isspace()
#define OUT 0 // Outside a word
#define IN 1 // Inside a word
int main() {
FILE *fp;
int character;
int word_count = 0;
int state = OUT;
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("Error: Could not open data.txt\n");
exit(1);
}
// Read character by character
while ((character = fgetc(fp)) != EOF) {
// Check if the character is a delimiter (space, tab, or newline)
if (isspace(character)) {
state = OUT; // We are outside a word
}
// If the character is NOT a delimiter AND we were OUT of a word
else if (state == OUT) {
state = IN; // We just started a new word
word_count++;
}
// If we are IN a word, do nothing and continue reading
}
fclose(fp);
printf("Total number of words in the file: %d\n", word_count);
return 0;
}Code language: C++ (cpp)
Explanation:
- This program uses a simple state machine to accurately count words. The
statevariable tracks whether the program is currentlyINa word orOUTof a word (i.e., at a delimiter). - The
isspace()function checks for any whitespace character (space, tab, newline, etc.). A word is counted only when the program transitions from theOUTstate to theINstate, meaning a non-delimiter character was just encountered after one or more delimiters. This correctly handles multiple spaces between words.
Exercise 7: Copy File
Practice Problem: Create a program to copy the entire content of a source file (data.txt updated in Exercise 3) to a destination file (destination.txt).
Expected Output:
destination.txt
Name: Alice Johnson
Age: 30 years
Date Appended: 2025-10-15
Status: Successfully appended.
+ Hint
You need two file pointers: one for the source file opened in read mode ("r") and one for the destination file opened in write mode ("w"). Read data from the source using fgetc() and write it immediately to the destination using fputc().
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *source_fp, *dest_fp;
int character;
// Open source file for reading
source_fp = fopen("data.txt", "r");
if (source_fp == NULL) {
perror("Error opening data.txt");
exit(1);
}
// Open destination file for writing (creates or overwrites)
dest_fp = fopen("destination.txt", "w");
if (dest_fp == NULL) {
perror("Error opening destination.txt");
fclose(source_fp); // Close source file before exiting
exit(1);
}
// Copy content character by character
while ((character = fgetc(source_fp)) != EOF) {
fputc(character, dest_fp); // Write the character to the destination file
}
// Close both files
fclose(source_fp);
fclose(dest_fp);
printf("File 'data.txt' successfully copied to 'destination.txt'.\n");
return 0;
}Code language: C++ (cpp)
Explanation:
- The program utilizes two separate file pointers. It reads one character at a time from the source file using
fgetc()until theEOFis reached. For every character read,fputc()is immediately used to write that same character to the destination file stream. - This is the most fundamental and robust method for binary or text file copying in C. Crucially, the program includes error checking for both file operations and ensures that the source file is closed even if the destination file fails to open.
Exercise 8: Display a Specific Line of a File
Practice Problem: Prompt the user to enter a line number N. Read a text file (e.g. data.txt updated in Exercise 3) and display the content of the Nth line on the console.
Expected Output:
Enter the line number to display: 2
--- Line 2 ---
Age: 30 years
--------------
+ Hint
Open the file in read mode. Use a loop and fgets() to read lines sequentially. Keep a line counter. Only print the line when the counter matches the user’s input N.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
char buffer[256];
int target_line, current_line = 0;
printf("Enter the line number to display: ");
if (scanf("%d", &target_line) != 1 || target_line < 1) {
printf("Invalid line number entered.\n");
return 1;
}
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("Error: Could not open data.txt\n");
return 1;
}
// Read lines one by one
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
current_line++;
// Check if the current line matches the target line
if (current_line == target_line) {
printf("\n--- Line %d ---\n", target_line);
printf("%s", buffer);
printf("--------------\n");
fclose(fp);
return 0; // Exit successfully after finding the line
}
}
fclose(fp);
// If the loop finishes without finding the line
printf("Error: Line %d not found (File has %d lines).\n", target_line, current_line);
return 0;
}Code language: C++ (cpp)
Explanation:
- After getting the desired
target_linefrom the user, the program reads the file line by line usingfgets(). - A
current_linecounter is incremented for every line successfully read. Whencurrent_lineequalstarget_line, the content of thebufferis printed, the file is closed, and the program exits. - If the loop finishes without the condition being met, it means the requested line number was greater than the total number of lines in the file.
Exercise 9: Write a Series of Numbers to a File
Practice Problem: Write a C program to write a sequence of integers from 1 to 10 to a new file named numbers.txt, ensuring each number is on a separate line.
Expected Output:
numbers.txt
1
2
3
...
10
+ Hint
Use a simple for loop that iterates from 1 to 10. Inside the loop, use fprintf() with the format specifier "%d\n" to write the integer followed by a newline character.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
int i;
fp = fopen("numbers.txt", "w");
if (fp == NULL) {
printf("Error opening file!\n");
exit(1);
}
printf("Writing numbers 1 to 10 to numbers.txt...\n");
// Loop from 1 to 10
for (i = 1; i <= 10; i++) {
// Write the number and a newline character to the file
fprintf(fp, "%d\n", i);
}
fclose(fp);
printf("Numbers successfully written.\n");
return 0;
}Code language: C++ (cpp)
Explanation:
- The file is opened in write mode (
"w"). A standardforloop is used to generate the numbers 1 through 10. - The key function is
fprintf(fp, "%d\n", i). The\n(newline character) appended to the format string is crucial, as it ensures that each subsequent number is written starting on a new line in the text file, fulfilling the problem requirement.
Exercise 10: Read Numbers and Calculate Sum
Practice Problem: Read the sequence of integers from the file numbers.txt (created in Exercise 9) and calculate and display their total sum.
Expected Output:
Reading numbers from file and calculating sum...
Successfully processed all numbers.
The total sum of the numbers is: 55
+ Hint
Open the file in read mode ("r"). Use a while loop combined with fscanf() to read the numbers. The loop should continue as long as fscanf() successfully reads an integer (i.e., returns 1).
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
int number;
int sum = 0;
int read_count;
fp = fopen("numbers.txt", "r");
if (fp == NULL) {
printf("Error opening file 'numbers.txt'.\n");
exit(1);
}
printf("Reading numbers from file and calculating sum...\n");
// Loop using fscanf() to read integers
// fscanf returns the number of successfully read items (should be 1)
while ((read_count = fscanf(fp, "%d", &number)) == 1) {
sum += number; // Add the read number to the total sum
// printf("Read: %d\n", number); // Uncomment for debugging
}
fclose(fp);
// Check if the loop ended because of EOF or a format mismatch
if (feof(fp)) {
printf("Successfully processed all numbers.\n");
printf("The total sum of the numbers is: %d\n", sum);
} else if (ferror(fp)) {
printf("An I/O error occurred during reading.\n");
} else {
// This happens if fscanf failed because it encountered non-integer data
printf("Error: Found non-numeric data in the file.\n");
}
return 0;
}Code language: C++ (cpp)
Explanation:
- The file is opened in read mode.
- The core of the program is the
whileloop condition:(read_count = fscanf(fp, "%d", &number)) == 1. Thefscanf()function attempts to read an integer from the file and store it at the address of thenumbervariable. It returns the count of items successfully matched and assigned. - As long as it returns
1, an integer was read and assigned, and it is added to thesum. Whenfscanf()reaches the end of the file or encounters non-numeric data, it will return a value other than1, terminating the loop.
Exercise 11: Uppercase Conversion
Practice Problem: Read the content of any existing text file (e.g. data.txt updated in Exercise 3) and write its content to a new file (output_upper.txt), converting all lowercase letters to uppercase letters. All other characters (numbers, symbols, spaces) should remain unchanged.
Expected Output:
output_upper.txt
NAME: ALICE JOHNSON
AGE: 30 YEARS
DATE APPENDED: 2025-10-15
STATUS: SUCCESSFULLY APPENDED.
+ Hint
Use two file pointers, one for reading ("r") and one for writing ("w"). Read the file character by character using fgetc(). Use the standard C library function toupper() (from <ctype.h>) to check and convert the character before writing it using fputc().
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> // For toupper()
int main() {
FILE *in_fp, *out_fp;
int character;
in_fp = fopen("data.txt", "r");
if (in_fp == NULL) {
perror("Error opening data.txt");
exit(1);
}
out_fp = fopen("output_upper.txt", "w");
if (out_fp == NULL) {
perror("Error opening output_upper.txt");
fclose(in_fp);
exit(1);
}
// Read character by character until EOF
while ((character = fgetc(in_fp)) != EOF) {
// Convert to uppercase (if it's a letter) and write to the output file
fputc(toupper(character), out_fp);
}
printf("Content copied to 'output_upper.txt' in uppercase.\n");
fclose(in_fp);
fclose(out_fp);
return 0;
}Code language: C++ (cpp)
Explanation:
The program reads the input file character by character using fgetc(). The retrieved character is passed directly to the toupper() function.
If the character is a lowercase letter, toupper() returns its uppercase equivalent; otherwise, it returns the character itself unchanged. This result is immediately written to the output file using fputc(). This ensures a perfect copy with only the casing modified.
Exercise 12: Remove Vowels from a File
Practice Problem: Read a any text file (e.g. data.txt updated in Exercise 3) and write its content to a new file (no_vowels.txt), excluding all lowercase and uppercase vowels (A, E, I, O, U, a, e, i, o, u).
Expected Output:
no_vowels.txt
Nm: lc Jhnsn
g: 30 yrs
Dt ppndd: 2025-10-15
Stts: Sccssflly ppndd.
+ Hint
- Use
fgetc()to read characters. - Within the loop, use a series of logical OR (
||) comparisons to check if the current character is a vowel (checking both cases). If it is not a vowel, write the character to the output file usingfputc().
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int is_vowel(char ch) {
switch (ch) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
return 1; // It is a vowel
default:
return 0; // It is not a vowel
}
}
int main() {
FILE *in_fp, *out_fp;
int character;
in_fp = fopen("data.txt", "r");
if (in_fp == NULL) {
perror("Error opening data.txt");
exit(1);
}
out_fp = fopen("no_vowels.txt", "w");
if (out_fp == NULL) {
perror("Error opening no_vowels.txt");
fclose(in_fp);
exit(1);
}
while ((character = fgetc(in_fp)) != EOF) {
// Write only if the character is NOT a vowel
if (!is_vowel(character)) {
fputc(character, out_fp);
}
}
printf("Vowels removed. Result saved in 'no_vowels.txt'.\n");
fclose(in_fp);
fclose(out_fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- This program defines a helper function,
is_vowel(), for clarity. - The main loop reads the file character by character. Inside the loop, the condition
!is_vowel(character)checks if the character is not a vowel (both upper and lower case). Only when this condition is true is the character written to the output file usingfputc(). - All vowel characters are simply skipped, effectively removing them from the copied content.
Exercise 13: Search for a Word
Practice Problem: Prompt the user to enter a filename (you can refer data.txt updated in Exercise 3) and a target word. Read the specified file and report the total number of times that target word appears in the file. Assume the file contains words separated by spaces or newlines.
Expected Output:
Enter the filename: data.txt
Enter the word to search: Johnson
The word 'Johnson' appears 1 times in 'data.txt'.
+ Hint
- Use
fscanf()within awhileloop to read the file word-by-word into a temporary string buffer. - Use the C string function
strcmp()(from<string.h>) to compare the word read from the file with the user’s target word.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // For strcmp()
int main() {
FILE *fp;
char filename[100];
char target_word[50];
char file_word[50];
int count = 0;
printf("Enter the filename: ");
scanf("%s", filename);
printf("Enter the word to search: ");
scanf("%s", target_word);
fp = fopen(filename, "r");
if (fp == NULL) {
perror("Error opening file");
exit(1);
}
// Read word by word from the file
// fscanf with %s reads a string until it hits whitespace
while (fscanf(fp, "%s", file_word) == 1) {
// Compare the word read from the file with the target word
// strcmp returns 0 if the strings are identical
if (strcmp(file_word, target_word) == 0) {
count++;
}
}
fclose(fp);
printf("\nThe word '%s' appears %d times in '%s'.\n", target_word, count, filename);
return 0;
}Code language: C++ (cpp)
Explanation:
- The program takes the filename and the
target_wordfrom the user. It then usesfscanf(fp, "%s", file_word)inside a loop. The%sformat specifier tellsfscanf()to read a string (a “word”) until it encounters any whitespace (space, tab, or newline) and stores it infile_word. - This elegantly handles word separation. The
strcmp()function performs a case-sensitive comparison. Whenstrcmp()returns0, the words match, and the counter is incremented.
Exercise 14: Replace Word in a File
Practice Problem: Read a any text file (you can refer data.txt updated in exercise 3) and replace all occurrences of a specific word (e.g., “the”) with a new word (e.g., “a”) and save the result to a new file (modified.txt).
Given:
sample.txt
The mouse that the cat hit that the dog bit that the fly landed on ran away
Expected Output:
The mouse that a cat hit that a dog bit that a fly landed on ran away
+ Hint
- Similar to Exercise 13, read the file word by word using
fscanf(). - Compare the read word with the word to be replaced. If they match, write the new word to the output file; otherwise, write the original word. Remember to add a space after each word written.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OLD_WORD "the"
#define NEW_WORD "a"
int main() {
FILE *in_fp, *out_fp;
char file_word[50];
in_fp = fopen("sample.txt", "r");
if (in_fp == NULL) {
perror("Error opening sample.txt");
exit(1);
}
out_fp = fopen("modified.txt", "w");
if (out_fp == NULL) {
perror("Error opening modified.txt");
fclose(in_fp);
exit(1);
}
// Read word by word
while (fscanf(in_fp, "%s", file_word) == 1) {
// Check if the word needs replacement
if (strcmp(file_word, OLD_WORD) == 0) {
fprintf(out_fp, "%s ", NEW_WORD); // Write the new word
} else {
fprintf(out_fp, "%s ", file_word); // Write the original word
}
}
printf("Word replacement complete. Saved to 'modified.txt'.\n");
fclose(in_fp);
fclose(out_fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- The program reads
sample.txtword by word usingfscanf(). - Inside the loop, it checks if
file_wordis equal to the predefinedOLD_WORDusingstrcmp(). If they are equal, theNEW_WORDis written tomodified.txtusingfprintf(); - otherwise, the original
file_wordis written. A space character is appended after every word written ("%s ") to maintain separation, sincefscanf("%s", ...)consumes the delimiter but doesn’t store it.
Exercise 15: Display File Content in Reverse
Practice Problem: Read a any text file and display its entire content character by character in reverse order (starting from the last character and ending with the first).
Given:
reverse_me.txt
Name: Alice Johnson
Age: 30 years
Expected Output:
Reversed content:
sraey 03 :egA
nosnhoJ ecilA :emaN
+ Hint
- This requires moving the file pointer.
- Use
fseek()withSEEK_ENDto find the end of the file, andftell()to get the total file size. Then, loop backward from the end, usingfseek()withSEEK_SETto position the pointer one character back, andfgetc()to read the character.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
long size, i;
int character;
fp = fopen("reverse_me.txt", "r");
if (fp == NULL) {
perror("Error opening reverse_me.txt");
exit(1);
}
// 1. Find the size of the file
fseek(fp, 0, SEEK_END); // Move pointer to the end
size = ftell(fp); // Get the current position (the size)
printf("Reversed content:\n");
// 2. Loop backward from size - 1 down to 0
for (i = size - 1; i >= 0; i--) {
// Move the pointer 'i' bytes from the beginning (SEEK_SET)
fseek(fp, i, SEEK_SET);
// Read the character at that position
character = fgetc(fp);
// Display the character
printf("%c", character);
}
printf("\n");
fclose(fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- This exercise heavily relies on
fseek()andftell()for random access (non-sequential I/O). - First,
fseek(fp, 0, SEEK_END)positions the pointer at the end of the file, andftell()retrieves this position, which is the file’s size in bytes. - The
forloop iterates backward fromsize - 1(the index of the last character) to0(the first character). - Inside the loop,
fseek(fp, i, SEEK_SET)moves the file pointer to the ith byte from the beginning, andfgetc()reads the character at that exact location.
Exercise 16: Merge Two Files
Practice Problem: Read the content of two separate files (file1.txt and file2.txt) and write their combined content sequentially into a third file (merged.txt).
Given:
file1.txt
This is file 1
file2.txt
This is file2
Expected Output:
merged.txt
This is file 1
--- End of File 1 ---
This is file 2
+ Hint
- Open three file pointers:
fp1andfp2for reading ("r") andfp_outfor writing ("w"). - Copy the entire content of
fp1tofp_out, and then copy the entire content offp2tofp_out. Use a character-by-character copy loop (withfgetc()andfputc()) for both source files.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
void copy_file(FILE *source, FILE *dest) {
int ch;
while ((ch = fgetc(source)) != EOF) {
fputc(ch, dest);
}
}
int main() {
FILE *fp1, *fp2, *fp_out;
fp1 = fopen("file1.txt", "r");
fp2 = fopen("file2.txt", "r");
fp_out = fopen("merged.txt", "w");
if (fp1 == NULL || fp2 == NULL || fp_out == NULL) {
perror("Error opening one or more files");
if (fp1) fclose(fp1);
if (fp2) fclose(fp2);
if (fp_out) fclose(fp_out);
exit(1);
}
// 1. Copy content of file1 to merged.txt
copy_file(fp1, fp_out);
// Optional: Add a newline or separator between the two files
fprintf(fp_out, "\n--- End of File 1 ---\n");
// 2. Copy content of file2 to merged.txt (appended)
copy_file(fp2, fp_out);
printf("Files merged successfully into 'merged.txt'.\n");
fclose(fp1);
fclose(fp2);
fclose(fp_out);
return 0;
}Code language: C++ (cpp)
Explanation:
- The program defines a reusable
copy_filefunction to handle the character-by-character transfer logic. It opens both source files in read mode and the destination file in write mode. - It calls
copy_filefirst withfp1as the source, and then withfp2as the source. Since the destination file pointer (fp_out) remains open, the second call tocopy_fileautomatically appends the content offile2.txtimmediately after the content offile1.txt.
Exercise 17: Tab to Spaces Conversion
Practice Problem: Read a file (tabbed.txt) and replace every tab character (\t) with exactly four space characters (), saving the result to a new file (spaced.txt).
Expected Output:
Tabs replaced with 4 spaces. Saved to 'spaced.txt'.
+ Hint
- Read the file character by character using
fgetc(). - Use a conditional check to see if the character is a tab (
'\t'). If it is, use a loop to write the required four spaces to the output file usingfputc(). - If it is any other character, write the original character directly.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
#define SPACES_PER_TAB 4
int main() {
FILE *in_fp, *out_fp;
int character, i;
in_fp = fopen("tabbed.txt", "r");
if (in_fp == NULL) {
perror("Error opening tabbed.txt");
exit(1);
}
out_fp = fopen("spaced.txt", "w");
if (out_fp == NULL) {
perror("Error opening spaced.txt");
fclose(in_fp);
exit(1);
}
while ((character = fgetc(in_fp)) != EOF) {
if (character == '\t') {
// If a tab is found, write 4 spaces instead
for (i = 0; i < SPACES_PER_TAB; i++) {
fputc(' ', out_fp);
}
} else {
// For any other character, write it as is
fputc(character, out_fp);
}
}
printf("Tabs replaced with %d spaces. Saved to 'spaced.txt'.\n", SPACES_PER_TAB);
fclose(in_fp);
fclose(out_fp);
return 0;
}Code language: C++ (cpp)
Explanation:
The program reads the input file using fgetc(). Inside the loop, it checks if the character is equal to the tab escape sequence ('\t'). If it is, a small for loop executes, writing the space character (' ') to the output file exactly four times using fputc().
If the character is not a tab, it is written to the output file unmodified.
Exercise 18: Simple Encryption (Caesar Cipher)
Practice Problem: Implement a simple Caesar cipher (shift by N=3) to encrypt the contents of an input file (plain.txt) and write the result to an output file (encrypted.txt). Only alphabet characters (A-Z, a-z) should be shifted; all others should be written as is.
Given:
plain.txt
Name: Alice Johnson
Age: 30 years
Expected Output:
encrypted.txt
Qdph: Dolfh Mrkqvrq
Djh: 30 bhduv
+ Hint
- Use
fgetc()to read the file character by character. - If the character is a letter, check its case. Apply the formula:
encrypted_char = (original_char - base + shift) % 26 + base. The base is'a'for lowercase and'A'for uppercase. - Non-alphabetic characters should bypass the encryption logic.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> // For isalpha(), isupper(), islower()
#define SHIFT 3
int main() {
FILE *in_fp, *out_fp;
int character, encrypted_char;
in_fp = fopen("plain.txt", "r");
if (in_fp == NULL) {
perror("Error opening plain.txt");
exit(1);
}
out_fp = fopen("encrypted.txt", "w");
if (out_fp == NULL) {
perror("Error opening encrypted.txt");
fclose(in_fp);
exit(1);
}
while ((character = fgetc(in_fp)) != EOF) {
encrypted_char = character; // Default: no change
if (isalpha(character)) {
int base;
if (islower(character)) {
base = 'a';
} else { // isupper(character)
base = 'A';
}
// Caesar Cipher formula
encrypted_char = (character - base + SHIFT) % 26 + base;
}
fputc(encrypted_char, out_fp);
}
printf("File encrypted with shift %d. Saved to 'encrypted.txt'.\n", SHIFT);
fclose(in_fp);
fclose(out_fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- The program reads the file character by character. It uses
isalpha()to check if the character is a letter. If it is, it determines thebase('a'or'A') usingislower()orisupper(). - The core Caesar cipher logic uses modular arithmetic:
(character - base)converts the letter to an index 0−25. Adding theSHIFTand taking the result modulo 26 wraps the index around the alphabet. - Finally, adding
baseconverts the index back into the shifted ASCII character. Non-alphabetic characters are written directly without modification.
Exercise 19: Simple Decryption (Caesar Cipher)
Practice Problem: Implement the corresponding decryption for the file (encrypted.txt) created in Exercise 19. The program should read the encrypted file and write the original plaintext to a new file (decrypted.txt).
Expected Output:
decrypted.txt
Name: Alice Johnson
Age: 30 years
+ Hint
- The decryption is the reverse of the encryption.
- Since the encryption used a positive shift, the decryption requires an equivalent negative shift.
- The formula becomes:
decrypted_char = (original_char - base - shift) % 26 + base. - Be careful with negative results of the modulo operator in C; a safer calculation is
(original_char - base - shift + 26) % 26 + base.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define SHIFT 3 // Must use the same shift value
int main() {
FILE *in_fp, *out_fp;
int character, decrypted_char;
in_fp = fopen("encrypted.txt", "r");
if (in_fp == NULL) {
perror("Error opening encrypted.txt");
exit(1);
}
out_fp = fopen("decrypted.txt", "w");
if (out_fp == NULL) {
perror("Error opening decrypted.txt");
fclose(in_fp);
exit(1);
}
while ((character = fgetc(in_fp)) != EOF) {
decrypted_char = character;
if (isalpha(character)) {
int base;
if (islower(character)) {
base = 'a';
} else {
base = 'A';
}
// Decryption formula (handling C's negative modulo behavior)
// The term '+ 26' ensures the result of the modulus is always positive.
decrypted_char = (character - base - SHIFT + 26) % 26 + base;
}
fputc(decrypted_char, out_fp);
}
printf("File successfully decrypted. Saved to 'decrypted.txt'.\n");
fclose(in_fp);
fclose(out_fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- The structure is identical to the encryption program, but the mathematical operation is reversed.
- Decryption requires subtracting the
SHIFTvalue. In C, the result of the modulo operator (%) can be negative if the numerator is negative. - To correctly handle the alphabet wrap-around (e.g., decrypting ‘C’ with a shift of 3 should result in ‘Z’), the expression includes an extra +26 before the final modulo operation:
(index - SHIFT + 26) % 26. This guarantees a positive result within the 0−25 range, ensuring the character correctly wraps backward from ‘a’ to ‘z’ or ‘A’ to ‘Z’.
Exercise 20: Write Student Record (Binary)
Practice Problem: Define a C struct Student containing name (string), roll_number (int), and marks (float). Write a single student’s record received from the user to a binary file named students.dat using fwrite().
Given:
// Student structure
struct Student {
char name[50];
int roll_number;
float marks;
};Code language: C++ (cpp)
Expected Output:
Enter Student Name: Jessa
Enter Roll Number: 25
Enter Marks: 85
Student record successfully written to students.dat (Binary).
+ Hint
- Open the file in write-binary mode (
"wb"). - Use the
sizeof()operator to determine the exact size of thestruct Studentto be written. - The function
fwrite()is essential here, as it writes the raw memory representation of the structure directly to the file.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
// Define the structure for a student record
struct Student {
char name[50];
int roll_number;
float marks;
};
int main() {
FILE *fp;
struct Student s;
// Get data from the user
printf("Enter Student Name: ");
scanf("%s", s.name);
printf("Enter Roll Number: ");
scanf("%d", &s.roll_number);
printf("Enter Marks: ");
scanf("%f", &s.marks);
// Open the file in write-binary mode ("wb")
fp = fopen("students.dat", "wb");
if (fp == NULL) {
perror("Error opening students.dat");
exit(1);
}
// Write the structure's data to the file
fwrite(&s, sizeof(struct Student), 1, fp);
printf("Student record successfully written to students.dat (Binary).\n");
fclose(fp);
return 0;
}Code language: C++ (cpp)
Explanation:
The file is opened in binary write mode ("wb"). The fwrite() function is used to write data. Its arguments are:
- The address of the data block to write (
&s). - The size of each item to write (
sizeof(struct Student)). - The number of items to write (1).
- The file pointer (
fp). This approach writes the structure as a continuous block of raw bytes, making it a highly efficient way to store structured, non-textual data.
Exercise 21: Read Student Record (Binary)
Practice Problem: Read the single student record from the binary file students.dat (created in Exercise 21) using fread() and display the student’s details on the console.
Given:
/ Re-define the structure
struct Student {
char name[50];
int roll_number;
float marks;
};Code language: C++ (cpp)
Expected Output:
--- Student Record Read ---
Name: Jessa
Roll Number: 25
Marks: 85.00
---------------------------
+ Hint
- Open the file in read-binary mode (
"rb"). - Use a
struct Studentvariable to hold the data read from the file. - The function
fread()should read exactly one item ofsizeof(struct Student).
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
// Re-define the structure
struct Student {
char name[50];
int roll_number;
float marks;
};
int main() {
FILE *fp;
struct Student s;
// Open the file in read-binary mode ("rb")
fp = fopen("students.dat", "rb");
if (fp == NULL) {
perror("Error opening students.dat");
exit(1);
}
// Read the structure's data from the file
// It returns the number of items successfully read (should be 1)
if (fread(&s, sizeof(struct Student), 1, fp) == 1) {
printf("\n--- Student Record Read ---\n");
printf("Name: %s\n", s.name);
printf("Roll Number: %d\n", s.roll_number);
printf("Marks: %.2f\n", s.marks);
printf("---------------------------\n");
} else {
printf("Error reading record or file is empty.\n");
}
fclose(fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- The file is opened in binary read mode (
"rb"). - The
fread()function is the counterpart tofwrite(). It attempts to read data into the memory location provided (&s). Since the function returns the number of items successfully read, checking if the return value is1confirms that a completeStudentrecord was successfully retrieved from the binary file.
Exercise 22: Multiple Records (Binary)
Practice Problem: Write the records of N students (where N is input by the user) to a new binary file, class.dat.
Given:
struct Student {
char name[50];
int roll_number;
float marks;
};Code language: C++ (cpp)
Expected Output:
Enter the number of students to record: 2
--- Student 1 ---
Name: Jessa
Roll Number: 25
Marks: 85
--- Student 2 ---
Name: Sam
Roll Number: 26
Marks: 88
2 student records successfully written to class.dat.
+ Hint
Use an array of struct Student or use a for loop to repeatedly prompt the user for input and call fwrite() for each student record.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
struct Student {
char name[50];
int roll_number;
float marks;
};
int main() {
FILE *fp;
struct Student s;
int n, i;
printf("Enter the number of students to record: ");
scanf("%d", &n);
fp = fopen("class.dat", "wb");
if (fp == NULL) {
perror("Error opening class.dat");
exit(1);
}
for (i = 0; i < n; i++) {
printf("\n--- Student %d ---\n", i + 1);
printf("Name: ");
scanf("%s", s.name);
printf("Roll Number: ");
scanf("%d", &s.roll_number);
printf("Marks: ");
scanf("%f", &s.marks);
// Write the record to the file
fwrite(&s, sizeof(struct Student), 1, fp);
}
printf("\n%d student records successfully written to class.dat.\n", n);
fclose(fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- The program uses a standard
forloop to iterate N times. - In each iteration, it prompts the user for the three fields of the
Studentstructure. Once the fields are populated,fwrite()is called, writing one complete block ofsizeof(struct Student)data to the file. - Since the file is open in binary mode, the records are stored contiguously, one after the other.
Exercise 23: Search and Display Record (Binary)
Practice Problem: Read the multiple student records from the binary file class.dat (created in Exercise 22) and allow the user to search for a student by their roll number, displaying their full details if found.
Given:
struct Student {
char name[50];
int roll_number;
float marks;
};Code language: C++ (cpp)
Expected Output:
Enter the Roll Number to search: 26
--- Record Found ---
Name: Sam
Roll Number: 26
Marks: 88.00
--------------------
+ Hint
- Read records sequentially using a
whileloop withfread(). - Check the return value of
fread()to know when EOF is reached. - Inside the loop, compare the
roll_numberin the structure with the user’s target roll number.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
struct Student {
char name[50];
int roll_number;
float marks;
};
int main() {
FILE *fp;
struct Student s;
int target_roll, found = 0;
printf("Enter the Roll Number to search: ");
scanf("%d", &target_roll);
fp = fopen("class.dat", "rb");
if (fp == NULL) {
perror("Error opening class.dat");
exit(1);
}
// Read records until EOF or error
while (fread(&s, sizeof(struct Student), 1, fp) == 1) {
if (s.roll_number == target_roll) {
printf("\n--- Record Found ---\n");
printf("Name: %s\n", s.name);
printf("Roll Number: %d\n", s.roll_number);
printf("Marks: %.2f\n", s.marks);
printf("--------------------\n");
found = 1;
break; // Stop searching once found
}
}
if (!found) {
printf("Student with Roll Number %d not found.\n", target_roll);
}
fclose(fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- The file is opened in binary read mode.
- The
whileloop repeatedly callsfread()to load the next record from the file into thesvariable. - If
fread()successfully reads a record (returns 1), the program compares the student’sroll_numberwith thetarget_roll. If they match, the details are printed, thefoundflag is set, and thebreakstatement exits the loop, improving efficiency.
Exercise 24: Update Record (Binary)
Practice Problem: Allow the user to update the marks of a specific student identified by their roll number in the binary file class.dat (created in Exercise 22). This requires using fseek() for direct access.
Given:
struct Student {
char name[50];
int roll_number;
float marks;
};Code language: C++ (cpp)
Expected Output:
Enter Roll Number to update marks for: 26
Enter new Marks: 92
Marks for Sam (Roll 26) successfully updated.
+ Hint
- Open the file in read/write binary mode (
"r+b"). - Search for the record sequentially. Once the record is found, use
fseek()to move the file pointer back to the start of the found record. - Update the record’s data in memory, and then use
fwrite()to overwrite the old data at that exact position.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
struct Student {
char name[50];
int roll_number;
float marks;
};
int main() {
FILE *fp;
struct Student s;
int target_roll, found = 0;
float new_marks;
long record_size = sizeof(struct Student);
printf("Enter Roll Number to update marks for: ");
scanf("%d", &target_roll);
printf("Enter new Marks: ");
scanf("%f", &new_marks);
// Open in read/write binary mode ("r+b")
fp = fopen("class.dat", "r+b");
if (fp == NULL) {
perror("Error opening class.dat");
exit(1);
}
// Read records sequentially
while (fread(&s, record_size, 1, fp) == 1) {
if (s.roll_number == target_roll) {
found = 1;
// 1. Move file pointer back to the start of the current record
// Current position = End of the record just read
// New position = Current position - size of the record
fseek(fp, -record_size, SEEK_CUR);
// 2. Update the marks in the memory structure
s.marks = new_marks;
// 3. Write the modified structure back, overwriting the old data
fwrite(&s, record_size, 1, fp);
printf("\nMarks for %s (Roll %d) successfully updated.\n", s.name, target_roll);
break;
}
}
if (!found) {
printf("Roll Number %d not found for update.\n", target_roll);
}
fclose(fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- The file is opened in
"r+b"mode, allowing both reading and writing (overwriting) of binary data. - The program reads records until the
target_rollis found. Crucially, after a successfulfread(), the file pointer is at the end of the record that was just read. - To overwrite this record,
fseek(fp, -record_size, SEEK_CUR)moves the pointer backward by the size of one record (record_size) from the current position (SEEK_CUR). - The in-memory structure
sis updated, andfwrite()then overwrites the old record’s data with the new data at the repositioned pointer.
Exercise 25: Determine File Size
Practice Problem: Write a program to find and display the size of a given file (e.g., class.dat created in Exercise 22) in bytes.
Expected Output:
The size of 'class.dat' is: 120 bytes
+ Hint
- Open the file in read mode (
"r"or"rb"). - Use
fseek()to move the file pointer to the end of the file, starting from the beginning (SEEK_END). - Then, use
ftell()to get the current position of the pointer, which will represent the total size of the file in bytes.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
long file_size = -1;
fp = fopen("class.dat", "rb");
if (fp == NULL) {
perror("Error opening class.dat");
exit(1);
}
// 1. Move the file pointer to the end of the file
if (fseek(fp, 0, SEEK_END) == 0) {
// 2. Get the current position (which is the file size)
file_size = ftell(fp);
} else {
perror("Error seeking to end of file");
}
fclose(fp);
if (file_size != -1) {
printf("The size of 'class.dat' is: %ld bytes\n", file_size);
} else {
printf("Could not determine file size.\n");
}
return 0;
}Code language: C++ (cpp)
Explanation:
This is the standard C method for finding file size.
- The call
fseek(fp, 0, SEEK_END)moves the file pointer zero bytes relative to the end of the file, placing it right after the last byte. - The function
ftell(fp)then returns the current absolute position of the pointer, measured from the beginning of the file. Since the pointer is at the end, the returned value is exactly the total size of the file in bytes.
Exercise 26: Robust Error Checking
Practice Problem: Write a program that attempts to open a non-existent file (missing.txt) for reading. Implement robust error checking using the NULL check and display a detailed system error message using perror() if the open operation fails.
Expected Output:
Attempting to open the file 'missing.txt'...
File Open Error: No such file or directory
Program will now exit.
+ Hint
Attempt to open a file that you know does not exist in read mode ("r"). Check the returned FILE pointer against NULL. If it is NULL, call perror() with a descriptive string.
+ Show Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
const char *filename = "missing.txt";
printf("Attempting to open the file '%s'...\n", filename);
// Attempt to open the file for reading
fp = fopen(filename, "r");
// Check if the file pointer is NULL (file open failed)
if (fp == NULL) {
// perror prints the given string followed by the system error message
// corresponding to the current errno value (e.g., "No such file or directory").
perror("File Open Error");
printf("Program will now exit.\n");
// Exit with a non-zero status code to indicate an error
exit(EXIT_FAILURE);
}
// Only executed if the file opened successfully
printf("File opened successfully (unexpected for missing.txt!).\n");
fclose(fp);
return 0;
}Code language: C++ (cpp)
Explanation:
- When
fopen()fails (e.g., file not found, permission denied), it returns aNULLpointer and sets a global integer variable namederrnoto an appropriate error code. - The program checks for the
NULLreturn. Theperror()function is the standard C mechanism for reporting such errors. It prints the string argument you pass (“File Open Error” in this case), followed by a colon and the system’s human-readable description of the error code stored inerrno. This provides much more informative output than a simple “File Error” message

Leave a Reply