Skip to the content
On this page
  1. The experiments
  2. Experiment 1 — Armstrong number
  3. Experiment 2 — Sum of digits
  4. Experiment 3 — Fibonacci series
  5. Experiment 4 — Largest and smallest
  6. Experiment 5 — Swap by value and address
  7. Experiment 6 — String operations
  8. Experiment 7 — Linear search
  9. Experiment 8 — Matrix addition
  10. Experiment 9 — Factorial by recursion
  11. Experiment 10 — Matrix multiplication
  12. Experiment 11 — Sort ascending
  13. Experiment 12 — Employee salary
  14. Experiment 13 — File read/write
  15. Experiment 14 — Reverse a file
  16. Experiment 15 — Book database
  17. Lab exam tips
  18. What the practical record should contain

15 experiments, each set out as 1. Question, 2. Aim, 3. Steps, 4. Programme, 5. Execution and Results.

Every program is in labs/course-2-c/ as a compilable .c file. All fifteen compile under gcc -Wall -Wextra with no warnings and were run against the sample inputs below. Each was run on a terminal, with its sample input typed at its prompts, so the output under 5. Execution and Results is what you would see, the typed values included.

Re-run the whole set:

bash tools/data-science/run_c_labs.sh

Compile and run one:

gcc -Wall -Wextra -o armstrong labs/course-2-c/01_armstrong.c
./armstrong

The experiments

# Experiment File Sample input Key idea
1 Armstrong number 01_armstrong.c 153 digit extraction with % 10 and / 10
2 Sum of digits 02_sum_of_digits.c 12345 same peeling loop
3 Fibonacci series 03_fibonacci.c 10 iterative, three variables
4 Largest and smallest 04_largest_smallest.c 5 then 23 7 91 4 56 seed with a[0], not 0
5 Swap by value and address 05_swap_value_address.c 10 20 the parameter-passing demo
6 String operations 06_string_operations.c Hello World library and hand-written versions
7 Linear search 07_linear_search.c 5, list, 30 return index, −1 for absent
8 Matrix addition 08_matrix_addition.c 2 2 then both matrices 2-D arrays passed to functions
9 Factorial by recursion 09_factorial_recursive.c 5 base case and recursive case
10 Matrix multiplication 10_matrix_multiplication.c 2 then both matrices three nested loops
11 Sort ascending 11_sort_ascending.c 6 then the list bubble sort with early exit
12 Employee salary 12_employee_salary.c 2 then two records structures and formatted output
13 File read/write 13_file_read_write.c none fopen, fprintf, fgets, fclose
14 Reverse a file 14_reverse_file.c none fseek from SEEK_END
15 Book database 15_book_file_crud.c menu choices full CRUD on a binary file

Experiment 1 — Armstrong number

1. Question

Check whether a number is an Armstrong number (here 153).

2. Aim

Decide whether a number equals the sum of its digits each raised to the number of digits.

3. Steps

  1. Count the digits.
  2. Raise a digit to a power.
  3. Read the number.
  4. Add each digit raised to the number of digits. % 10 takes the last digit and / 10 drops it.
  5. Compare the sum with the number.

THE METHOD

An n-digit number equals the sum of its digits each raised to the power n. 153 = 1³ + 5³ + 3³. You must count the digits first to know the exponent — that step is what most students miss. 1634 is a four-digit Armstrong number: 1⁴ + 6⁴ + 3⁴ + 4⁴ = 1 + 1296 + 81 + 256 = 1634.

4. Programme

/* Experiment 1: Check whether a given number is an Armstrong number.
 *
 * An Armstrong number of n digits equals the sum of its own digits each
 * raised to the power n.  153 -> 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153.
 *
 * Sample input:  153
 * Sample output: 153 is an Armstrong number
 */
#include <stdio.h>

/* Step 1: Count the digits */
int count_digits(int n)
{
    int digits = 0;
    if (n == 0)
        return 1;
    while (n > 0) {
        digits++;
        n /= 10;
    }
    return digits;
}

/* Step 2: Raise a digit to a power */
int power(int base, int exp)
{
    int result = 1, i;
    for (i = 0; i < exp; i++)
        result *= base;
    return result;
}

int main(void)
{
    int num, temp, digit, sum = 0, n;

    /* Step 3: Read the number */
    printf("Enter a number: ");
    if (scanf("%d", &num) != 1) {
        printf("Invalid input\n");
        return 1;
    }

    /* Step 4: Add each digit raised to the number of digits */
    n = count_digits(num);
    temp = num;
    while (temp > 0) {
        digit = temp % 10;
        sum += power(digit, n);
        temp /= 10;
    }

    /* Step 5: Compare the sum with the number */
    if (sum == num)
        printf("%d is an Armstrong number\n", num);
    else
        printf("%d is not an Armstrong number\n", num);
    return 0;
}

5. Execution and Results

OUTPUT

Enter a number: 153
153 is an Armstrong number

RESULT

153 = 1³ + 5³ + 3³, so 153 is an Armstrong number.

Experiment 2 — Sum of digits

1. Question

Find the sum of the digits of a number (here 12345).

2. Aim

Add the digits of a number by peeling them off one at a time.

3. Steps

  1. Read the number.
  2. Peel off each digit and add it.
  3. Print the sum.

4. Programme

/* Experiment 2: Find the sum of individual digits of a positive integer.
 *
 * Sample input:  12345
 * Sample output: Sum of digits of 12345 = 15
 */
#include <stdio.h>

int main(void)
{
    int num, temp, sum = 0;

    /* Step 1: Read the number */
    printf("Enter a positive integer: ");
    if (scanf("%d", &num) != 1 || num < 0) {
        printf("Please enter a positive integer\n");
        return 1;
    }

    /* Step 2: Peel off each digit and add it */
    temp = num;
    while (temp > 0) {
        sum += temp % 10;   /* peel off the last digit */
        temp /= 10;         /* and drop it */
    }

    /* Step 3: Print the sum */
    printf("Sum of digits of %d = %d\n", num, sum);
    return 0;
}

5. Execution and Results

OUTPUT

Enter a positive integer: 12345
Sum of digits of 12345 = 15

RESULT

The digits of 12345 add to 15.

Experiment 3 — Fibonacci series

1. Question

Print the first n terms of the Fibonacci series (here 10).

2. Aim

Generate the series iteratively, with three variables.

3. Steps

  1. Read the number of terms.
  2. Print each term and move the pair on. long long holds more terms before it overflows.

4. Programme

/* Experiment 3: Generate the first n terms of the Fibonacci sequence.
 *
 * Sample input:  10
 * Sample output: 0 1 1 2 3 5 8 13 21 34
 */
#include <stdio.h>

int main(void)
{
    int n, i;
    long long first = 0, second = 1, next;

    /* Step 1: Read the number of terms */
    printf("Enter the number of terms: ");
    if (scanf("%d", &n) != 1 || n <= 0) {
        printf("Please enter a positive number of terms\n");
        return 1;
    }

    /* Step 2: Print each term and move the pair on */
    printf("Fibonacci sequence: ");
    for (i = 0; i < n; i++) {
        printf("%lld", first);
        if (i < n - 1)
            printf(" ");
        next = first + second;
        first = second;
        second = next;
    }
    printf("\n");
    return 0;
}

5. Execution and Results

OUTPUT

Enter the number of terms: 10
Fibonacci sequence: 0 1 1 2 3 5 8 13 21 34

RESULT

The first ten terms are 0 1 1 2 3 5 8 13 21 34.

Experiment 4 — Largest and smallest

1. Question

Find both the largest and the smallest number in a list (here 23, 7, 91, 4, 56).

2. Aim

Find the extremes of a list in one pass.

3. Steps

  1. Read the numbers.
  2. Seed both with the first element. Not 0, which breaks on a list of negative numbers.
  3. Compare every other element.
  4. Print the two.

4. Programme

/* Experiment 4: Find both the largest and the smallest number in a list.
 *
 * Sample input:  5
 *                23 7 91 4 56
 * Sample output: Largest  = 91
 *                Smallest = 4
 */
#include <stdio.h>

#define MAX 100

int main(void)
{
    int list[MAX], n, i, largest, smallest;

    /* Step 1: Read the numbers */
    printf("How many numbers? ");
    if (scanf("%d", &n) != 1 || n <= 0 || n > MAX) {
        printf("Please enter a count between 1 and %d\n", MAX);
        return 1;
    }

    printf("Enter %d numbers: ", n);
    for (i = 0; i < n; i++) {
        if (scanf("%d", &list[i]) != 1) {
            printf("Invalid input\n");
            return 1;
        }
    }

    /* Step 2: Seed both with the first element */
    /* Seed both with the first element -- not with 0, which breaks on
       all-negative lists. */
    largest = smallest = list[0];
    /* Step 3: Compare every other element */
    for (i = 1; i < n; i++) {
        if (list[i] > largest)
            largest = list[i];
        if (list[i] < smallest)
            smallest = list[i];
    }

    /* Step 4: Print the two */
    printf("Largest  = %d\n", largest);
    printf("Smallest = %d\n", smallest);
    return 0;
}

5. Execution and Results

OUTPUT

How many numbers? 5
Enter 5 numbers: 23 7 91 4 56
Largest  = 91
Smallest = 4

RESULT

The largest is 91 and the smallest 4.

Experiment 5 — Swap by value and address

1. Question

Swap two numbers using call by value and call by address (here 10 and 20).

2. Aim

Show that only call by address changes the caller's variables.

3. Steps

  1. Swap by value: the function gets copies.
  2. Swap by address: the function gets pointers.
  3. Read two integers.
  4. Call by value: before, inside, after.
  5. Call by address: before, inside, after.

THE METHOD

The most examined program in the course. Make sure your output shows all three states — before, inside the function, after — for both methods. The point is visible only in the contrast: call by value prints 10 20 after the call, call by address prints 20 10.

4. Programme

/* Experiment 5: Demonstrate the change in parameter values while swapping two
 * integers using Call by Value and Call by Address.
 *
 * This is the classic exam question on parameter passing.  Call by value swaps
 * only the function's private copies, so the caller sees nothing change.  Call
 * by address passes the addresses, so the function reaches the originals.
 *
 * Sample input:  10 20
 */
#include <stdio.h>

/* Step 1: Swap by value: the function gets copies */
void swap_by_value(int a, int b)
{
    int temp = a;
    a = b;
    b = temp;
    printf("  inside swap_by_value  : a = %d, b = %d\n", a, b);
}

/* Step 2: Swap by address: the function gets pointers */
void swap_by_address(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
    printf("  inside swap_by_address: a = %d, b = %d\n", *a, *b);
}

int main(void)
{
    int x, y;

    /* Step 3: Read two integers */
    printf("Enter two integers: ");
    if (scanf("%d %d", &x, &y) != 2) {
        printf("Invalid input\n");
        return 1;
    }

    /* Step 4: Call by value: before, inside, after */
    printf("\nCALL BY VALUE\n");
    printf("  before: x = %d, y = %d\n", x, y);
    swap_by_value(x, y);
    printf("  after : x = %d, y = %d   <- unchanged\n", x, y);

    /* Step 5: Call by address: before, inside, after */
    printf("\nCALL BY ADDRESS\n");
    printf("  before: x = %d, y = %d\n", x, y);
    swap_by_address(&x, &y);
    printf("  after : x = %d, y = %d   <- swapped\n", x, y);
    return 0;
}

5. Execution and Results

OUTPUT

Enter two integers: 10 20

CALL BY VALUE
  before: x = 10, y = 20
  inside swap_by_value  : a = 20, b = 10
  after : x = 10, y = 20   <- unchanged

CALL BY ADDRESS
  before: x = 10, y = 20
  inside swap_by_address: a = 20, b = 10
  after : x = 20, y = 10   <- swapped

RESULT

Both functions swap their own copies, but only call by address changes x and y: after it they are 20 and 10, while after call by value they are still 10 and 20.

Experiment 6 — String operations

1. Question

Perform the string operations — length, compare, copy, concatenate, reverse — with the library functions and with functions of your own (here on Hello and World).

2. Aim

Use the string library, and write its functions by hand.

3. Steps

  1. Hand-written strlen and strcpy.
  2. Hand-written strcmp and reverse.
  3. Read two strings.
  4. The library functions.
  5. The hand-written versions.

4. Programme

/* Experiment 6: Perform various string operations.
 *
 * Shows both the library functions from <string.h> and hand-written versions,
 * because exams commonly ask you to implement strlen/strcpy/strcmp yourself.
 *
 * Sample input:  Hello
 *                World
 */
#include <stdio.h>
#include <string.h>

/* Step 1: Hand-written strlen and strcpy */
/* Hand-written equivalents -- the "write it without the library" exam question. */
int my_strlen(const char *s)
{
    int len = 0;
    while (s[len] != '\0')
        len++;
    return len;
}

void my_strcpy(char *dest, const char *src)
{
    int i = 0;
    while (src[i] != '\0') {
        dest[i] = src[i];
        i++;
    }
    dest[i] = '\0';
}

/* Step 2: Hand-written strcmp and reverse */
int my_strcmp(const char *a, const char *b)
{
    int i = 0;
    while (a[i] != '\0' && a[i] == b[i])
        i++;
    return a[i] - b[i];
}

void my_strrev(char *s)
{
    int i = 0, j = my_strlen(s) - 1;
    char temp;
    while (i < j) {
        temp = s[i];
        s[i] = s[j];
        s[j] = temp;
        i++;
        j--;
    }
}

int main(void)
{
    char s1[100], s2[100], copy[200], joined[200];

    /* Step 3: Read two strings */
    printf("Enter first string : ");
    if (scanf("%99s", s1) != 1) return 1;
    printf("Enter second string: ");
    if (scanf("%99s", s2) != 1) return 1;

    /* Step 4: The library functions */
    printf("\nLibrary functions\n");
    printf("  strlen(s1)     = %d\n", (int) strlen(s1));
    printf("  strcmp(s1, s2) = %d\n", strcmp(s1, s2));

    strcpy(joined, s1);
    strcat(joined, s2);
    printf("  strcat(s1, s2) = %s\n", joined);

    /* Step 5: The hand-written versions */
    printf("\nHand-written versions\n");
    printf("  my_strlen(s1)     = %d\n", my_strlen(s1));
    printf("  my_strcmp(s1, s2) = %d\n", my_strcmp(s1, s2));

    my_strcpy(copy, s1);
    printf("  my_strcpy -> %s\n", copy);

    my_strrev(copy);
    printf("  my_strrev -> %s\n", copy);
    return 0;
}

5. Execution and Results

OUTPUT

Enter first string : Hello
Enter second string: World

Library functions
  strlen(s1)     = 5
  strcmp(s1, s2) = -15
  strcat(s1, s2) = HelloWorld

Hand-written versions
  my_strlen(s1)     = 5
  my_strcmp(s1, s2) = -15
  my_strcpy -> Hello
  my_strrev -> olleH

RESULT

Both versions agree: the length of Hello is 5, and Hello compares below World (−15, the difference of H and W). The copy is Hello, reversed olleH, and the two joined HelloWorld.

1. Question

Search a list for an element by linear search (here 30 in 10, 20, 30, 40, 50).

2. Aim

Find an element's position, or report that it is absent.

3. Steps

  1. Search, returning the index or -1.
  2. Read the list and the key.
  3. Search, and report the position.

4. Programme

/* Experiment 7: Search for an element in a given list of values.
 *
 * Linear search: check each element in turn.  Worst case O(n).
 *
 * Sample input:  5
 *                10 20 30 40 50
 *                30
 * Sample output: 30 found at position 3 (index 2)
 */
#include <stdio.h>

#define MAX 100

/* Step 1: Search, returning the index or -1 */
int linear_search(const int list[], int n, int key)
{
    int i;
    for (i = 0; i < n; i++) {
        if (list[i] == key)
            return i;       /* found -- return the index */
    }
    return -1;              /* the conventional "not found" marker */
}

int main(void)
{
    int list[MAX], n, i, key, pos;

    /* Step 2: Read the list and the key */
    printf("How many elements? ");
    if (scanf("%d", &n) != 1 || n <= 0 || n > MAX) return 1;

    printf("Enter %d elements: ", n);
    for (i = 0; i < n; i++)
        if (scanf("%d", &list[i]) != 1) return 1;

    printf("Enter the element to search: ");
    if (scanf("%d", &key) != 1) return 1;

    /* Step 3: Search, and report the position */
    pos = linear_search(list, n, key);
    if (pos == -1)
        printf("%d is not present in the list\n", key);
    else
        printf("%d found at position %d (index %d)\n", key, pos + 1, pos);
    return 0;
}

5. Execution and Results

OUTPUT

How many elements? 5
Enter 5 elements: 10 20 30 40 50
Enter the element to search: 30
30 found at position 3 (index 2)

RESULT

30 is at position 3 (index 2).

Experiment 8 — Matrix addition

1. Question

Use functions to add two matrices (here two 2 × 2 matrices).

2. Aim

Pass 2-D arrays to functions to read, add and print them.

3. Steps

  1. Read a matrix.
  2. Add two matrices.
  3. Print a matrix.
  4. Read the order and both matrices.
  5. Add them, and print the sum.

4. Programme

/* Experiment 8: Use functions to add two matrices.
 *
 * Sample input:  2 2
 *                1 2 3 4
 *                5 6 7 8
 * Sample output: 6 8
 *                10 12
 */
#include <stdio.h>

#define MAX 10

/* Step 1: Read a matrix */
void read_matrix(int m[MAX][MAX], int rows, int cols, const char *name)
{
    int i, j;
    printf("Enter %d elements of matrix %s: ", rows * cols, name);
    for (i = 0; i < rows; i++)
        for (j = 0; j < cols; j++)
            if (scanf("%d", &m[i][j]) != 1)
                return;
}

/* Step 2: Add two matrices */
void add_matrices(int a[MAX][MAX], int b[MAX][MAX], int sum[MAX][MAX],
                  int rows, int cols)
{
    int i, j;
    for (i = 0; i < rows; i++)
        for (j = 0; j < cols; j++)
            sum[i][j] = a[i][j] + b[i][j];
}

/* Step 3: Print a matrix */
void print_matrix(int m[MAX][MAX], int rows, int cols)
{
    int i, j;
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++)
            printf("%4d", m[i][j]);
        printf("\n");
    }
}

int main(void)
{
    int a[MAX][MAX], b[MAX][MAX], sum[MAX][MAX];
    int rows, cols;

    /* Step 4: Read the order and both matrices */
    printf("Enter rows and columns: ");
    if (scanf("%d %d", &rows, &cols) != 2 ||
        rows <= 0 || cols <= 0 || rows > MAX || cols > MAX) {
        printf("Dimensions must be between 1 and %d\n", MAX);
        return 1;
    }

    read_matrix(a, rows, cols, "A");
    read_matrix(b, rows, cols, "B");
    /* Step 5: Add them, and print the sum */
    add_matrices(a, b, sum, rows, cols);

    printf("\nA + B =\n");
    print_matrix(sum, rows, cols);
    return 0;
}

5. Execution and Results

OUTPUT

Enter rows and columns: 2 2
Enter 4 elements of matrix A: 1 2 3 4
Enter 4 elements of matrix B: 5 6 7 8

A + B =
   6   8
  10  12

RESULT

A + B = [6 8; 10 12].

Experiment 9 — Factorial by recursion

1. Question

Find the factorial of a number using recursion (here 5).

2. Aim

Compute n! recursively, refusing the inputs it cannot handle.

3. Steps

  1. The recursive function: a base case and a recursive case.
  2. Read n, refusing a negative or an overflow. 21! does not fit in 64 bits.
  3. Print n!.

4. Programme

/* Experiment 9: Calculate the factorial of a given integer using recursion.
 *
 * The exam almost always asks you to identify the base case and the recursive
 * case, so they are labelled below.
 *
 * Sample input:  5
 * Sample output: 5! = 120
 */
#include <stdio.h>

/* Step 1: The recursive function: a base case and a recursive case */
unsigned long long factorial(int n)
{
    if (n == 0 || n == 1)          /* BASE CASE -- stops the recursion */
        return 1;
    return (unsigned long long) n * factorial(n - 1);  /* RECURSIVE CASE */
}

int main(void)
{
    int n;

    /* Step 2: Read n, refusing a negative or an overflow */
    printf("Enter a non-negative integer: ");
    if (scanf("%d", &n) != 1 || n < 0) {
        printf("Factorial is not defined for negative numbers\n");
        return 1;
    }
    if (n > 20) {
        printf("%d! overflows a 64-bit integer\n", n);
        return 1;
    }

    /* Step 3: Print n! */
    printf("%d! = %llu\n", n, factorial(n));
    return 0;
}

5. Execution and Results

OUTPUT

Enter a non-negative integer: 5
5! = 120

RESULT

5! = 120.

Experiment 10 — Matrix multiplication

1. Question

Multiply two square matrices (here two 2 × 2 matrices).

2. Aim

Multiply matrices with three nested loops.

3. Steps

  1. Multiply: reset each cell, then accumulate.
  2. Read the order and both matrices.
  3. Multiply them, and print the product.

THE METHOD

Three nested loops, and c[i][j] must be reset to 0 before the innermost loop accumulates into it. Verify by hand on 2×2 matrices before trusting your code:

[1 2] × [5 6] = [1×5+2×7  1×6+2×8] = [19 22]
[3 4]   [7 8]   [3×5+4×7  3×6+4×8]   [43 50]

4. Programme

/* Experiment 10: Multiplication of two N x N matrices.
 *
 * C[i][j] = sum over k of A[i][k] * B[k][j]
 *
 * Sample input:  2
 *                1 2 3 4
 *                5 6 7 8
 * Sample output: 19 22
 *                43 50
 */
#include <stdio.h>

#define MAX 10

/* Step 1: Multiply: reset each cell, then accumulate */
void multiply(int a[MAX][MAX], int b[MAX][MAX], int c[MAX][MAX], int n)
{
    int i, j, k;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            c[i][j] = 0;                 /* must reset before accumulating */
            for (k = 0; k < n; k++)
                c[i][j] += a[i][k] * b[k][j];
        }
    }
}

int main(void)
{
    int a[MAX][MAX], b[MAX][MAX], c[MAX][MAX];
    int n, i, j;

    /* Step 2: Read the order and both matrices */
    printf("Enter N (order of the square matrices): ");
    if (scanf("%d", &n) != 1 || n <= 0 || n > MAX) return 1;

    printf("Enter %d elements of matrix A: ", n * n);
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            if (scanf("%d", &a[i][j]) != 1) return 1;

    printf("Enter %d elements of matrix B: ", n * n);
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            if (scanf("%d", &b[i][j]) != 1) return 1;

    /* Step 3: Multiply them, and print the product */
    multiply(a, b, c, n);

    printf("\nA x B =\n");
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++)
            printf("%6d", c[i][j]);
        printf("\n");
    }
    return 0;
}

5. Execution and Results

OUTPUT

Enter N (order of the square matrices): 2
Enter 4 elements of matrix A: 1 2 3 4
Enter 4 elements of matrix B: 5 6 7 8

A x B =
    19    22
    43    50

RESULT

A × B = [19 22; 43 50], as worked by hand.

Experiment 11 — Sort ascending

1. Question

Sort a list in ascending order (here 64, 34, 25, 12, 22, 11).

2. Aim

Sort by bubble sort, stopping as soon as a pass makes no swap.

3. Steps

  1. Bubble sort, with an early exit.
  2. Read the list.
  3. Sort it, and print it.

4. Programme

/* Experiment 11: Sort a given list of integers in ascending order.
 *
 * Bubble sort, with the early-exit flag -- exams ask for the flag as the
 * "optimised" version.  Best case O(n) on already-sorted data, worst O(n^2).
 *
 * Sample input:  6
 *                64 34 25 12 22 11
 * Sample output: 11 12 22 25 34 64
 */
#include <stdio.h>

#define MAX 100

/* Step 1: Bubble sort, with an early exit */
void bubble_sort(int list[], int n)
{
    int i, j, temp, swapped;
    for (i = 0; i < n - 1; i++) {
        swapped = 0;
        for (j = 0; j < n - 1 - i; j++) {
            if (list[j] > list[j + 1]) {
                temp = list[j];
                list[j] = list[j + 1];
                list[j + 1] = temp;
                swapped = 1;
            }
        }
        if (!swapped)       /* nothing moved -- the list is already sorted */
            break;
    }
}

int main(void)
{
    int list[MAX], n, i;

    /* Step 2: Read the list */
    printf("How many elements? ");
    if (scanf("%d", &n) != 1 || n <= 0 || n > MAX) return 1;

    printf("Enter %d elements: ", n);
    for (i = 0; i < n; i++)
        if (scanf("%d", &list[i]) != 1) return 1;

    /* Step 3: Sort it, and print it */
    bubble_sort(list, n);

    printf("Sorted list: ");
    for (i = 0; i < n; i++)
        printf("%d ", list[i]);
    printf("\n");
    return 0;
}

5. Execution and Results

OUTPUT

How many elements? 6
Enter 6 elements: 64 34 25 12 22 11
Sorted list: 11 12 22 25 34 64

RESULT

The sorted list is 11 12 22 25 34 64.

Experiment 12 — Employee salary

1. Question

Using a structure, compute the gross and net salary of employees from their basic pay.

2. Aim

Hold each employee's record in a structure, and compute the pay by the syllabus rules.

3. Steps

  1. The employee structure.
  2. The salary rules, in order.
  3. Read each employee and compute the pay.
  4. Print the table.

THE METHOD

The rules from the syllabus, in order — each depends on the one before:

DA        = 30% of Basic Pay
HRA       = 15% of Basic Pay
Deduction = 10% of (Basic Pay + DA)      <- includes DA, not just basic
Gross     = Basic Pay + DA + HRA
Net       = Gross − Deduction

For a basic pay of 50,000: DA = 15,000, HRA = 7,500, Deduction = 10% of 65,000 = 6,500, Gross = 72,500, Net = 66,000.

4. Programme

/* Experiment 12: Calculate the salaries of all employees using an Employee
 * structure (ID, Name, Designation, Basic Pay, DA, HRA, Gross, Deduction, Net).
 *
 * Rules given in the syllabus:
 *   DA        = 30% of Basic Pay
 *   HRA       = 15% of Basic Pay
 *   Deduction = 10% of (Basic Pay + DA)
 *   Gross     = Basic Pay + DA + HRA
 *   Net       = Gross - Deduction
 *
 * Sample input:  2
 *                101 Alice Manager 50000
 *                102 Bob Clerk 20000
 */
#include <stdio.h>

#define MAX_EMP 50

/* Step 1: The employee structure */
struct Employee {
    int   id;
    char  name[50];
    char  designation[50];
    float basic_pay;
    float da;
    float hra;
    float gross_salary;
    float deduction;
    float net_salary;
};

/* Step 2: The salary rules, in order */
void compute_salary(struct Employee *e)
{
    e->da        = 0.30f * e->basic_pay;
    e->hra       = 0.15f * e->basic_pay;
    e->deduction = 0.10f * (e->basic_pay + e->da);
    e->gross_salary = e->basic_pay + e->da + e->hra;
    e->net_salary   = e->gross_salary - e->deduction;
}

int main(void)
{
    struct Employee staff[MAX_EMP];
    int n, i;

    /* Step 3: Read each employee and compute the pay */
    printf("How many employees? ");
    if (scanf("%d", &n) != 1 || n <= 0 || n > MAX_EMP) return 1;

    for (i = 0; i < n; i++) {
        printf("Employee %d (id name designation basic_pay): ", i + 1);
        if (scanf("%d %49s %49s %f", &staff[i].id, staff[i].name,
                  staff[i].designation, &staff[i].basic_pay) != 4)
            return 1;
        compute_salary(&staff[i]);
    }

    /* Step 4: Print the table */
    printf("\n%-6s %-12s %-12s %10s %9s %9s %10s %10s %10s\n",
           "ID", "Name", "Designation", "Basic", "DA", "HRA",
           "Gross", "Deduction", "Net");
    for (i = 0; i < n; i++) {
        printf("%-6d %-12s %-12s %10.2f %9.2f %9.2f %10.2f %10.2f %10.2f\n",
               staff[i].id, staff[i].name, staff[i].designation,
               staff[i].basic_pay, staff[i].da, staff[i].hra,
               staff[i].gross_salary, staff[i].deduction, staff[i].net_salary);
    }
    return 0;
}

5. Execution and Results

OUTPUT

How many employees? 2
Employee 1 (id name designation basic_pay): 101 Alice Manager 50000
Employee 2 (id name designation basic_pay): 102 Bob Clerk 20000

ID     Name         Designation       Basic        DA       HRA      Gross  Deduction        Net
101    Alice        Manager        50000.00  15000.00   7500.00   72500.00    6500.00   66000.00
102    Bob          Clerk          20000.00   6000.00   3000.00   29000.00    2600.00   26400.00

RESULT

Alice's basic pay of 50,000 gives a gross of 72,500 and a net of 66,000; Bob's 20,000 gives 29,000 and 26,400.

Experiment 13 — File read/write

1. Question

Write text to a file and read it back.

2. Aim

Open, write, close, reopen and read a text file.

3. Steps

  1. Write three lines.
  2. Read them back.

4. Programme

/* Experiment 13: Read data from / write data to a file.
 *
 * Demonstrates the full cycle: fopen in "w" mode, fprintf, fclose, then
 * fopen in "r" mode, fgets, fclose.  Always check that fopen succeeded --
 * that check is worth marks.
 *
 * Takes no input; writes and reads back sample.txt in the current directory.
 */
#include <stdio.h>

int main(void)
{
    FILE *fp;
    char line[256];
    const char *filename = "sample.txt";

    /* Step 1: Write three lines */
    fp = fopen(filename, "w");
    if (fp == NULL) {
        printf("Error: could not open %s for writing\n", filename);
        return 1;
    }
    fprintf(fp, "Data Science Major 2025\n");
    fprintf(fp, "Problem Solving Using C\n");
    fprintf(fp, "File handling demonstration\n");
    fclose(fp);
    printf("Data written to %s\n\n", filename);

    /* Step 2: Read them back */
    fp = fopen(filename, "r");
    if (fp == NULL) {
        printf("Error: could not open %s for reading\n", filename);
        return 1;
    }
    printf("Contents of %s:\n", filename);
    while (fgets(line, sizeof(line), fp) != NULL)
        printf("  %s", line);
    fclose(fp);
    return 0;
}

5. Execution and Results

OUTPUT

Data written to sample.txt

Contents of sample.txt:
  Data Science Major 2025
  Problem Solving Using C
  File handling demonstration

RESULT

The three lines written to sample.txt are read back unchanged.

Experiment 14 — Reverse a file

1. Question

Copy the contents of a file into another in reverse order.

2. Aim

Read a file backwards with fseek, and write what it reads.

3. Steps

  1. Create the input file.
  2. Copy it backwards, one byte at a time from the end.
  3. Show both files.

THE METHOD

fseek(fp, -i, SEEK_END) for i = 1, 2, 3… walks backwards from the end one byte at a time. Open in binary mode ("rb") so no line-ending translation interferes.

4. Programme

/* Experiment 14: Reverse the contents of a file and store the result in
 * another file.
 *
 * Method: seek to the end, then walk backwards one byte at a time with
 * fseek(fp, -offset, SEEK_END), writing each character to the output file.
 *
 * Creates input.txt, then produces reversed.txt from it.
 */
#include <stdio.h>

int main(void)
{
    FILE *in, *out;
    long size, i;
    int ch;

    /* Step 1: Create the input file */
    /* Create the input file so the program is self-contained. */
    in = fopen("input.txt", "w");
    if (in == NULL) {
        printf("Error: could not create input.txt\n");
        return 1;
    }
    fprintf(in, "ABCDEFG");
    fclose(in);

    in = fopen("input.txt", "rb");
    if (in == NULL) {
        printf("Error: could not open input.txt\n");
        return 1;
    }
    out = fopen("reversed.txt", "wb");
    if (out == NULL) {
        printf("Error: could not create reversed.txt\n");
        fclose(in);
        return 1;
    }

    /* Step 2: Copy it backwards, one byte at a time from the end */
    fseek(in, 0, SEEK_END);
    size = ftell(in);

    for (i = 1; i <= size; i++) {
        fseek(in, -i, SEEK_END);
        ch = fgetc(in);
        if (ch == EOF)
            break;
        fputc(ch, out);
    }

    fclose(in);
    fclose(out);

    /* Step 3: Show both files */
    /* Show the result. */
    printf("input.txt    : ");
    in = fopen("input.txt", "r");
    while ((ch = fgetc(in)) != EOF) putchar(ch);
    fclose(in);

    printf("\nreversed.txt : ");
    out = fopen("reversed.txt", "r");
    while ((ch = fgetc(out)) != EOF) putchar(ch);
    fclose(out);
    printf("\n");
    return 0;
}

5. Execution and Results

OUTPUT

input.txt    : ABCDEFG
reversed.txt : GFEDCBA

RESULT

ABCDEFG is written out as GFEDCBA.

Experiment 15 — Book database

1. Question

Create a Book structure (ISBN, Title, Author, Price, Pages, Publisher), store book details in a file, and add, search, update and delete books by ISBN.

2. Aim

Keep records in a binary file, and carry out all four operations on it.

3. Steps

  1. The book record.
  2. Print a book.
  3. Add: append a record.
  4. Search by ISBN.
  5. Update: overwrite the record in place.
  6. Delete: copy the rest to a temporary file.
  7. Display all.
  8. The menu.

THE METHOD

The largest program in the list. Four operations on a binary file of struct Book records:

That last technique is the one to remember: you cannot delete bytes from the middle of a file. Rewriting to a temporary file is the standard answer.

4. Programme

/* Experiment 15: Create a Book structure (ISBN, Title, Author, Price, Pages,
 * Publisher), store book details in a file, and perform:
 *   a. Add book details
 *   b. Search for a book by ISBN and display it if present
 *   c. Update a book's details using its ISBN
 *   d. Delete a book by ISBN and display the remaining books
 *
 * This is the largest program in the lab list: it combines structures, file
 * I/O and a menu-driven loop.
 *
 * The delete operation uses the standard technique -- copy every record except
 * the doomed one into a temporary file, then rename it over the original.  You
 * cannot remove bytes from the middle of a file in place.
 *
 * Sample input (a menu choice, then what that choice asks for):
 *   1
 *   111 C_Programming Balaguruswamy 450.00 500 TMH
 *   1
 *   222 Python_Basics Thareja 550.00 600 Oxford
 *   2
 *   111
 *   3
 *   111 600.00
 *   4
 *   222
 *   5
 *   6
 */
#include <stdio.h>
#include <string.h>

#define DATAFILE "books.dat"
#define TEMPFILE "temp.dat"

/* Step 1: The book record */
struct Book {
    int   isbn;
    char  title[50];
    char  author[50];
    float price;
    int   pages;
    char  publisher[50];
};

/* Step 2: Print a book */
static void print_header(void)
{
    printf("%-8s %-20s %-15s %10s %7s %-15s\n",
           "ISBN", "Title", "Author", "Price", "Pages", "Publisher");
}

static void print_book(const struct Book *b)
{
    printf("%-8d %-20s %-15s %10.2f %7d %-15s\n",
           b->isbn, b->title, b->author, b->price, b->pages, b->publisher);
}

/* (a) Append one book to the data file. */
/* Step 3: Add: append a record */
void add_book(void)
{
    struct Book b;
    FILE *fp = fopen(DATAFILE, "ab");
    if (fp == NULL) {
        printf("Error: cannot open %s\n", DATAFILE);
        return;
    }
    printf("Enter ISBN title author price pages publisher: ");
    if (scanf("%d %49s %49s %f %d %49s", &b.isbn, b.title, b.author,
              &b.price, &b.pages, b.publisher) != 6) {
        printf("Invalid book details\n");
        fclose(fp);
        return;
    }
    fwrite(&b, sizeof(b), 1, fp);
    fclose(fp);
    printf("Book %d added\n", b.isbn);
}

/* (b) Search by ISBN. */
/* Step 4: Search by ISBN */
void search_book(void)
{
    struct Book b;
    int isbn, found = 0;
    FILE *fp = fopen(DATAFILE, "rb");
    if (fp == NULL) {
        printf("No books stored yet\n");
        return;
    }
    printf("Enter ISBN to search: ");
    if (scanf("%d", &isbn) != 1) {
        fclose(fp);
        return;
    }
    while (fread(&b, sizeof(b), 1, fp) == 1) {
        if (b.isbn == isbn) {
            print_header();
            print_book(&b);
            found = 1;
            break;
        }
    }
    fclose(fp);
    if (!found)
        printf("Book with ISBN %d not found\n", isbn);
}

/* (c) Update a book's price, writing the record back in place. */
/* Step 5: Update: overwrite the record in place */
void update_book(void)
{
    struct Book b;
    int isbn, found = 0;
    float new_price;
    FILE *fp = fopen(DATAFILE, "rb+");
    if (fp == NULL) {
        printf("No books stored yet\n");
        return;
    }
    printf("Enter ISBN to update and the new price: ");
    if (scanf("%d %f", &isbn, &new_price) != 2) {
        fclose(fp);
        return;
    }
    while (fread(&b, sizeof(b), 1, fp) == 1) {
        if (b.isbn == isbn) {
            b.price = new_price;
            /* Step back over the record just read, then overwrite it. */
            fseek(fp, -(long) sizeof(b), SEEK_CUR);
            fwrite(&b, sizeof(b), 1, fp);
            found = 1;
            break;
        }
    }
    fclose(fp);
    printf(found ? "Book %d updated\n" : "Book with ISBN %d not found\n", isbn);
}

/* (d) Delete by ISBN: copy all survivors to a temp file, then rename. */
/* Step 6: Delete: copy the rest to a temporary file */
void delete_book(void)
{
    struct Book b;
    int isbn, found = 0;
    FILE *fp, *temp;

    fp = fopen(DATAFILE, "rb");
    if (fp == NULL) {
        printf("No books stored yet\n");
        return;
    }
    temp = fopen(TEMPFILE, "wb");
    if (temp == NULL) {
        printf("Error: cannot create temporary file\n");
        fclose(fp);
        return;
    }
    printf("Enter ISBN to delete: ");
    if (scanf("%d", &isbn) != 1) {
        fclose(fp);
        fclose(temp);
        return;
    }
    while (fread(&b, sizeof(b), 1, fp) == 1) {
        if (b.isbn == isbn)
            found = 1;              /* skip it -- this is the deletion */
        else
            fwrite(&b, sizeof(b), 1, temp);
    }
    fclose(fp);
    fclose(temp);

    remove(DATAFILE);
    rename(TEMPFILE, DATAFILE);

    if (found)
        printf("Book %d deleted\n", isbn);
    else
        printf("Book with ISBN %d not found\n", isbn);
}

/* Step 7: Display all */
void display_all(void)
{
    struct Book b;
    int count = 0;
    FILE *fp = fopen(DATAFILE, "rb");
    if (fp == NULL) {
        printf("No books stored yet\n");
        return;
    }
    print_header();
    while (fread(&b, sizeof(b), 1, fp) == 1) {
        print_book(&b);
        count++;
    }
    fclose(fp);
    printf("(%d book(s))\n", count);
}

/* Step 8: The menu */
int main(void)
{
    int choice;

    for (;;) {
        printf("\n1.Add  2.Search  3.Update  4.Delete  5.Display all  6.Exit\n");
        printf("Enter your choice: ");
        if (scanf("%d", &choice) != 1)
            break;

        switch (choice) {
        case 1: add_book();     break;
        case 2: search_book();  break;
        case 3: update_book();  break;
        case 4: delete_book();  break;
        case 5: display_all();  break;
        case 6: printf("Exiting\n"); return 0;
        default: printf("Invalid choice\n");
        }
    }
    return 0;
}

5. Execution and Results

OUTPUT


1.Add  2.Search  3.Update  4.Delete  5.Display all  6.Exit
Enter your choice: 1
Enter ISBN title author price pages publisher: 111 C_Programming Balaguruswamy 450.00 500 TMH
Book 111 added

1.Add  2.Search  3.Update  4.Delete  5.Display all  6.Exit
Enter your choice: 1
Enter ISBN title author price pages publisher: 222 Python_Basics Thareja 550.00 600 Oxford
Book 222 added

1.Add  2.Search  3.Update  4.Delete  5.Display all  6.Exit
Enter your choice: 2
Enter ISBN to search: 111
ISBN     Title                Author               Price   Pages Publisher
111      C_Programming        Balaguruswamy       450.00     500 TMH

1.Add  2.Search  3.Update  4.Delete  5.Display all  6.Exit
Enter your choice: 3
Enter ISBN to update and the new price: 111 600.00
Book 111 updated

1.Add  2.Search  3.Update  4.Delete  5.Display all  6.Exit
Enter your choice: 4
Enter ISBN to delete: 222
Book 222 deleted

1.Add  2.Search  3.Update  4.Delete  5.Display all  6.Exit
Enter your choice: 5
ISBN     Title                Author               Price   Pages Publisher
111      C_Programming        Balaguruswamy       600.00     500 TMH
(1 book(s))

1.Add  2.Search  3.Update  4.Delete  5.Display all  6.Exit
Enter your choice: 6
Exiting

RESULT

Two books are added, book 111 is found and its price updated to 600.00, book 222 is deleted, and the file then holds one book.


Lab exam tips

  1. Write the program on paper first. Terminals are scarce and time is short.
  2. Compile early and often. One error at a time is manageable; twenty is not.
  3. Read the error message. "Expected ; before int" means the missing semicolon is on the line above the one named.

  4. Test edge cases before the examiner does: n = 0, an empty array, a negative number, a file that does not exist.

  5. Print prompts. printf("Enter n: ") before every scanf. Marks are given for a usable interface.

  6. Comment the logic, not the syntax. /* peel off the last digit */ is useful; /* increment i */ is not.

  7. Expect a viva. Be ready for "why did you use a while here?" and "what happens if I enter 0?"

What the practical record should contain

For each experiment, the five parts set out above: 1. Question, the task as set; 2. Aim, in one line; 3. Steps, the method in numbered steps; 4. Programme, the program, each step marked by a comment; 5. Execution and Results, what it printed for the sample input, and the result in words.