Board paper

Structured Programming in C 2022 Board Question Paper

ITM 102 · Structured Programming in C

Programme
BITM / BIM
Academic year
Semester 1
Exam year
2022 AD
Sitting
regular
Full marks
60
Duration
180 minutes

Tribhuvan University

Faculty of Management

Office of the Dean

2022 AD / Regular Examination

Course: ITM 102 · Structured Programming in C

Level: Bachelor of Information Technology Management (BITM / BIM) (BITM / BIM) · Semester 1

Full Marks: 60

Time: 3 hrs.

Time: 3 Hrs. | Full Marks: 60 | Pass Marks: 30

Subjective Questions

  1. Define algorithm.

    [2]
    View model solution

    Concept of Algorithm

    An algorithm is a finite, ordered sequence of well-defined, unambiguous, and computationally effective instructions designed to solve a specific problem or perform a computation.

    Key Characteristics of an Algorithm:

    1. Finiteness: Must terminate after a countable number of steps.
    2. Definiteness: Every step must be clear, precise, and unambiguous.
    3. Input: Accepts zero or more well-defined inputs.
    4. Output: Produces at least one well-defined result or output.
    5. Effectiveness: Every operation must be feasible and basic enough to be executed in finite time.

    Example (Algorithm to Find the Greater of Two Numbers):

    Step 1: Start
    Step 2: Declare variables A and B
    Step 3: Read values of A and B
    Step 4: If A > B then
              Print "A is greater"
            Else
              Print "B is greater"
    Step 5: Stop
    
  2. List any two modes for opening a file.

    [2]
    View model solution

    Modes for Opening a File in C

    Files in C are opened using the fopen() library function declared in <stdio.h>. Two primary opening modes are:

    1. "r" (Read Mode):

      • Opens an existing file for reading operations.
      • If the specified file does not exist on disk, fopen() returns NULL.
      • The file pointer is positioned at the very beginning of the file.
    2. "w" (Write Mode):

      • Creates a new file for writing operations.
      • If a file with the specified name already exists, its existing contents are completely truncated (erased) to 0 bytes.

    Other common modes include "a" (Append), "r+" (Read and Write), and "wb" (Binary Write).

  3. What is the use of printf() function?

    [2]
    View model solution

    Use of the printf() Function in C

    The printf() function (short for print formatted) is a standard library output function declared in <stdio.h>.

    Primary Functions:

    1. Console Output: Writes formatted text characters, strings, and variable values to the standard output stream (stdout, usually the terminal screen).
    2. Format Conversion: Translates internal binary representations of variables into human-readable text representations using format specifiers (e.g., %d for integers, %f for floats, %c for characters, %s for strings).
    3. Layout Control: Supports width, precision, and alignment formatting flags (e.g., %8.2f).

    Syntax & Example:

    #include <stdio.h>
    
    int main() {
        int roll = 101;
        float marks = 85.50;
        // Formatted output
        printf("Roll Number: %d | Marks: %.2f\n", roll, marks);
        return 0;
    }
    
  4. List arithmetic and logical operators available in C.

    [2]
    View model solution

    Arithmetic and Logical Operators in C

    1. Arithmetic Operators:

    Used to perform standard mathematical calculations on numeric operands:

    Operator Operation Example (a=10, b=3) Result
    + Addition a + b 13
    - Subtraction a - b 7
    * Multiplication a * b 30
    / Division (Integer truncation) a / b 3
    % Modulus (Remainder of integer division) a % b 1

    2. Logical Operators:

    Used to combine or negate conditional expressions; evaluate to 1 (True) or 0 (False):

    Operator Meaning Example Evaluates To
    && Logical AND (10 > 5) && (3 < 8) 1 (True if both true)
    &#124;&#124; Logical OR (10 < 5) &#124;&#124; (3 < 8) 1 (True if either true)
    ! Logical NOT !(10 > 5) 0 (Inverts truth value)
  5. Define iteration.

    [2]
    View model solution

    Concept of Iteration

    Iteration (commonly known as looping) is the repetitive execution of a sequence of programming statements until a predetermined termination condition is satisfied.

    Four Key Components of an Iteration Construct:

    1. Initialization: Setting the starting value of the loop control variable (e.g., int i = 0).
    2. Loop Continuation Condition: A Boolean expression evaluated before (or after) each cycle; if true, the loop body runs.
    3. Loop Body: The block of operational code executed on each iteration.
    4. Updation (Increment/Decrement): Modifies the loop counter towards the termination condition to prevent infinite loops (e.g., i++).

    In C, iteration is implemented using for, while, and do-while loops.

  6. Write a syntax to initialized 2D array in C.

    [2]
    View model solution

    Syntax to Initialize a 2D Array in C

    A two-dimensional array represents data in a row-column tabular format (stored in row-major order in contiguous memory).

    1. General Syntax:

    data_type array_name[row_size][column_size] = {
        {r0_c0, r0_c1, ..., r0_cn},
        {r1_c0, r1_c1, ..., r1_cn}
    };
    

    2. Practical Examples:

    // Method A: Explicit row-wise grouping (recommended for readability)
    int matrix[2][3] = {
        {10, 20, 30},
        {40, 50, 60}
    };
    
    // Method B: Linear sequential initialization (compiler maps row-major)
    int table[2][2] = {1, 2, 3, 4};
    
    // Method C: Unspecified row dimension (inferred by compiler)
    int grid[][2] = { {5, 6}, {7, 8} };
    
  7. What are the differences between array and structure?

    [2]
    View model solution

    Differences Between Array and Structure in C

    Basis of Comparison Array Structure (struct)
    Data Homogeneity Collection of elements of the same data type (homogeneous). Collection of elements of different data types (heterogeneous).
    Element Access Elements are accessed using a zero-based integer index (e.g., arr[2]). Members are accessed by name using the dot operator (e.g., s.roll) or arrow operator (->).
    Memory Allocation Strictly contiguous memory of uniform element size. Contiguous memory for member fields, but may include alignment padding bytes.
    Keyword No special keyword used; declared via square brackets []. Defined using the struct keyword.
    Pointer Representation Array name decays directly into a pointer to its first element. Structure name represents the whole variable; requires & to get its address.
  8. What is the advantage of global variable?

    [2]
    View model solution

    Advantages of Global Variables in C

    A global variable is declared outside all functions (typically at the top of the file) and retains its memory location in the static data segment throughout the entire execution lifetime of the program.

    Primary Advantages:

    1. Universal Accessibility: Accessible by any function within the same compilation unit without needing to be passed repeatedly through parameter lists.
    2. Persistent State: Retains its current updated value across multiple function calls, unlike automatic local variables which are re-created on the stack upon entry and destroyed on exit.
    3. Cross-Module Communication: Can be shared across separate .c source files by declaring them with the extern storage class specifier.
    4. Convenience in Embedded/System Programming: Simplifies sharing hardware registers, configuration flags, and buffer descriptors across interrupt service routines (ISRs).
  9. What is the use of malloc() function?

    [2]
    View model solution

    Use of the malloc() Function in C

    The malloc() (memory allocation) function is a core dynamic memory management function declared in <stdlib.h>.

    Key Uses & Properties:

    1. Dynamic Heap Allocation: Allocates a single contiguous block of raw memory of a requested size (in bytes) from the system heap at runtime.
    2. Returns Generic Pointer: Returns a void* pointer to the first byte of the allocated block, which can be typecast to any data pointer type (e.g., int*, char*).
    3. Preserves Flexibility: Enables programs to request the exact memory required based on runtime user input (e.g., dynamic arrays) rather than static compile-time array limits.
    4. Error Handling: Returns NULL if sufficient memory cannot be allocated.

    Syntax:

    ptr = (cast_type*) malloc(number_of_elements * sizeof(data_type));
    

    Example:

    int *arr = (int*) malloc(5 * sizeof(int));
    if (arr == NULL) {
        printf("Memory allocation failed!\n");
    }
    
  10. Define string.

    [2]
    View model solution

    Definition of String in C

    In C programming, a string is defined as a one-dimensional array of characters terminated by a special null character ('\0', ASCII value 0).

    Key Characteristics:

    1. No Primitive Type: C does not feature a built-in native string primitive type; strings are stored as null-terminated character sequences in character arrays (char str[size]) or referenced by pointers (char *ptr).
    2. Null Terminator ('\0'): Acts as the sentinel marker so that standard library string functions (like strlen(), strcpy(), and printf("%s")) determine where the valid string content ends.
    3. Storage Size: A string with (N) characters requires an array size of at least (N + 1) bytes to accommodate the terminating '\0'.
    4. Example: The string literal "NEPAL" contains 5 letters but occupies 6 bytes in memory: ['N', 'E', 'P', 'A', 'L', '\0'].
  11. Write a program to find the greatest of three number using functions. The function should expect three integers and return the greatest of them.

    [5]
    View model solution

    Program: Greatest of Three Numbers Using Function

    #include <stdio.h>
    
    // Function prototype: expects three integers and returns the greatest
    int findGreatest(int a, int b, int c);
    
    int main() {
        int num1, num2, num3, greatest;
    
        printf("=== Greatest of Three Numbers ===\n");
        printf("Enter three integer numbers: ");
        if (scanf("%d %d %d", &num1, &num2, &num3) != 3) {
            printf("Invalid input! Please enter integers.\n");
            return 1;
        }
    
        // Call user-defined function
        greatest = findGreatest(num1, num2, num3);
    
        printf("The greatest among %d, %d, and %d is: %d\n", num1, num2, num3, greatest);
    
        return 0;
    }
    
    // Function definition
    int findGreatest(int a, int b, int c) {
        if (a >= b && a >= c) {
            return a;
        } else if (b >= a && b >= c) {
            return b;
        } else {
            return c;
        }
    }
    

    Explanation:

    1. The function findGreatest takes three parameters (int a, int b, int c).
    2. It uses compound relational and logical conditions (&&) to evaluate which integer is greater than or equal to both peers.
    3. The function returns the winning integer value back to main(), where it is printed.
  12. Read a string from the user and find the length of that sting using strlen() function.

    [5]
    View model solution

    Program: Read String and Find Length Using strlen()

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char str[100];
        size_t length;
    
        printf("=== String Length Counter ===\n");
        printf("Enter a string: ");
    
        // Using fgets to safely read strings containing spaces
        if (fgets(str, sizeof(str), stdin) != NULL) {
            // Strip trailing newline character added by fgets if present
            size_t len = strlen(str);
            if (len > 0 && str[len - 1] == '\n') {
                str[len - 1] = '\0';
            }
    
            // Calculate string length using standard library function
            length = strlen(str);
    
            printf("Entered String : \"%s\"\n", str);
            printf("String Length  : %zu characters\n", length);
        }
    
        return 0;
    }
    

    Explanation:

    1. fgets(str, sizeof(str), stdin) reads user input safely, preventing buffer overflows.
    2. strlen(str) from <string.h> counts the number of characters in the string up to, but not including, the terminating null character ('\0').
  13. Differentiate between while and do-while loop. Write a program to print the multiples of 5 less than 100.

    [5]
    View model solution

    Difference Between while and do-while Loop & Program

    1. Comparison Table:

    Feature while Loop do-while Loop
    Control Type Entry-controlled loop. Exit-controlled loop.
    Condition Check Condition is tested before executing the loop body. Condition is tested after executing the loop body.
    Minimum Executions 0 times (if the condition is initially false). At least 1 time guaranteed.
    Syntax Syntax while (condition) { ... } do { ... } while (condition);
    Trailing Semicolon No semicolon after condition. Mandatory semicolon after while(cond);

    2. C Program: Multiples of 5 Less Than 100

    #include <stdio.h>
    
    int main() {
        int num = 5;
    
        printf("=== Multiples of 5 Less Than 100 ===\n");
        while (num < 100) {
            printf("%d ", num);
            num += 5; // Increment by 5
        }
        printf("\n");
    
        return 0;
    }
    

    Output: 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95

  14. Write a program that prints the following pattern: 1 1 2 1 2 3 1 2 3 4 1 2 3 5

    [5]
    View model solution

    Program: Pattern Printing

    The requested pattern consists of 5 rows of incrementing integers:

    1
    1 2
    1 2 3
    1 2 3 4
    1 2 3 4 5
    
    #include <stdio.h>
    
    int main() {
        int i, j;
        int rows = 5;
    
        printf("=== Pattern Output ===\n");
        for (i = 1; i <= rows; i++) {
            for (j = 1; j <= i; j++) {
                // Note: If strictly following the typo on row 5 from the paper (1 2 3 5),
                // we can adjust j, but standard TU curricula examine standard triangular sequence.
                if (i == 5 && j == 4) {
                    printf("%d ", 4); // handles 1 2 3 4 5 standard sequence
                } else {
                    printf("%d ", j);
                }
            }
            printf("\n");
        }
    
        return 0;
    }
    

    Step-by-Step Logic:

    1. Outer loop for (i = 1; i <= rows; i++) controls the current row index from 1 to 5.
    2. Inner loop for (j = 1; j <= i; j++) runs (i) times and prints the sequence of numbers from (1) up to (i).
    3. printf("\n") shifts output to the next line after completing each row.
  15. Write a program to find the factorial of a number N read from the user using recursive function.

    [5]
    View model solution

    Program: Factorial Using Recursive Function

    #include <stdio.h>
    
    // Recursive function to calculate factorial
    long long factorial(int n) {
        // Base case: factorial of 0 or 1 is 1
        if (n <= 1) {
            return 1;
        }
        // Recursive call: n! = n * (n - 1)!
        return (long long)n * factorial(n - 1);
    }
    
    int main() {
        int n;
    
        printf("=== Recursive Factorial Calculator ===\n");
        printf("Enter a non-negative integer: ");
        if (scanf("%d", &n) != 1 || n < 0) {
            printf("Error: Input must be a positive integer or zero.\n");
            return 1;
        }
    
        printf("Factorial of %d is: %lld\n", n, factorial(n));
    
        return 0;
    }
    

    Working Mechanism:

    • For (n = 4):
      • factorial(4) calls 4 * factorial(3)
      • factorial(3) calls 3 * factorial(2)
      • factorial(2) calls 2 * factorial(1)
      • factorial(1) hits base case, returning 1
      • Unwinding: (2 \times 1 = 2 \rightarrow 3 \times 2 = 6 \rightarrow 4 \times 6 = 24).
  16. Write a program to sort the numbers in an array.

    [5]
    View model solution

    Program: Sort Numbers in an Array in Ascending Order

    #include <stdio.h>
    
    int main() {
        int arr[100], n, i, j, temp;
    
        printf("=== Array Sorting (Bubble Sort) ===\n");
        printf("Enter number of elements in array: ");
        if (scanf("%d", &n) != 1 || n <= 0 || n > 100) {
            printf("Invalid array size!\n");
            return 1;
        }
    
        printf("Enter %d numbers:\n", n);
        for (i = 0; i < n; i++) {
            scanf("%d", &arr[i]);
        }
    
        // Bubble Sort Algorithm
        for (i = 0; i < n - 1; i++) {
            for (j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // Swap adjacent out-of-order elements
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    
        printf("\nSorted array in ascending order:\n");
        for (i = 0; i < n; i++) {
            printf("%d ", arr[i]);
        }
        printf("\n");
    
        return 0;
    }
    

    Logic:

    1. In each outer pass (i), adjacent elements arr[j] and arr[j+1] are compared.
    2. If the current element is greater than the next, they are swapped using a temporary variable.
    3. After (n-1) passes, the entire array is sorted in non-decreasing order.
  17. What does nested loop mean? Write a program to find the area of the rectangle after taking length and breadth as input from the user.

    [5]
    View model solution

    Nested Loop Concept & Rectangle Area Program

    1. Concept of Nested Loop:

    A nested loop refers to placing one loop construct completely inside the body of another loop construct.

    • The outer loop controls the primary repetition cycle (e.g., table rows).
    • For each single iteration of the outer loop, the inner loop executes completely from start to finish.
    • Total number of inner operations = (Iterations of Outer Loop) (\times) (Iterations of Inner Loop).

    2. C Program: Area of a Rectangle

    #include <stdio.h>
    
    int main() {
        float length, breadth, area;
    
        printf("=== Area of Rectangle Calculator ===\n");
        printf("Enter length of the rectangle: ");
        scanf("%f", &length);
    
        printf("Enter breadth of the rectangle: ");
        scanf("%f", &breadth);
    
        if (length <= 0 || breadth <= 0) {
            printf("Error: Dimensions must be positive numbers.\n");
            return 1;
        }
    
        // Formula: Area = Length * Breadth
        area = length * breadth;
    
        printf("\nLength  : %.2f units\n", length);
        printf("Breadth : %.2f units\n", breadth);
        printf("Area    : %.2f sq. units\n", area);
    
        return 0;
    }
    
  18. Write a program to read a string and copy it to another string in reverse format. Finally display the original string and the reversed string, without using string handling function.

    [5]
    View model solution

    Program: Reverse String Without String Handling Functions

    #include <stdio.h>
    
    int main() {
        char orig[100], rev[100];
        int len = 0, i, j;
    
        printf("=== String Reversal (Without string.h) ===\n");
        printf("Enter a string: ");
    
        // Read input string using fgets
        if (fgets(orig, sizeof(orig), stdin) != NULL) {
            // Find length manually without strlen()
            while (orig[len] != '\0') {
                if (orig[len] == '\n') {
                    orig[len] = '\0'; // Remove newline
                    break;
                }
                len++;
            }
    
            // Copy characters in reverse order into rev array
            j = 0;
            for (i = len - 1; i >= 0; i--) {
                rev[j] = orig[i];
                j++;
            }
            rev[j] = '\0'; // Append null character at the end
    
            printf("\nOriginal String : %s\n", orig);
            printf("Reversed String : %s\n", rev);
        }
    
        return 0;
    }
    

    Algorithm:

    1. Traverse orig using a while loop to find len manually without calling strlen().
    2. Set index (i = len - 1) and iterate backwards down to 0.
    3. Assign rev[j] = orig[i] and increment (j).
    4. Terminate rev with null character '\0' at index (j).
  19. Write a program to read an integer from the user. If the given integer is odd then write it into the file named “Odd.dat”, otherwise write it into “Even.dat”.

    [5]
    View model solution

    Program: Classify Odd/Even Integer into File

    #include <stdio.h>
    
    int main() {
        int num;
        FILE *fp;
    
        printf("=== Odd / Even File Classifier ===\n");
        printf("Enter an integer: ");
        if (scanf("%d", &num) != 1) {
            printf("Invalid integer input!\n");
            return 1;
        }
    
        if (num % 2 != 0) {
            // Odd number -> Write into Odd.dat
            fp = fopen("Odd.dat", "a");
            if (fp == NULL) {
                printf("Error opening Odd.dat for writing!\n");
                return 1;
            }
            fprintf(fp, "%d\n", num);
            fclose(fp);
            printf("Successfully appended odd number %d to 'Odd.dat'.\n", num);
        } else {
            // Even number -> Write into Even.dat
            fp = fopen("Even.dat", "a");
            if (fp == NULL) {
                printf("Error opening Even.dat for writing!\n");
                return 1;
            }
            fprintf(fp, "%d\n", num);
            fclose(fp);
            printf("Successfully appended even number %d to 'Even.dat'.\n", num);
        }
    
        return 0;
    }
    

    Explanation:

    1. The program uses modulo operator (num % 2) to test parity.
    2. fopen(filename, "a") opens the appropriate target file in append mode, creating it if it does not yet exist.
    3. fprintf() writes the number followed by a newline, and fclose() commits the stream.
  20. Give the syntax of the function in graphics that is used to draw a circle. Draw a flowchart to find the average of n numbers given by the user.

    [5]
    View model solution

    Graphics Circle Syntax & Flowchart for Average of N Numbers

    1. Syntax of circle() in C Graphics:

    In Turbo C/Borland C++ (<graphics.h>), the function to draw a circle is:

    void circle(int x, int y, int radius);
    
    • x: The horizontal x-coordinate of the circle’s center point.
    • y: The vertical y-coordinate of the circle’s center point.
    • radius: The radius of the circle in pixels.

    Example: circle(250, 200, 50); draws a circle centered at ((250, 200)) with radius 50.


    2. Flowchart: Average of N Numbers

             [ START ]
                 |
                 v
           [ Input N ]
                 |
                 v
        [ sum = 0, count = 0 ]
                 |
                 +-----> [ count < N ? ] ----- (NO) -----> [ avg = sum / N ]
                 |              |                                 |
                 |            (YES)                               v
                 |              |                           [ Output avg ]
                 |              v                                 |
                 |       [ Input num ]                            v
                 |              |                              [ STOP ]
                 |              v
                 |      [ sum = sum + num ]
                 |              |
                 |              v
                 |     [ count = count + 1 ]
                 |              |
                 +--------------+
    
  21. What do you mean by enumerations? Explain call by value and call by reference. Write a program to swap two floating type numbers using call by reference.

    [10]
    View model solution

    Enumeration, Parameter Passing & Float Swap Program

    1. Concept of Enumerations (enum):

    An enumeration is a user-defined data type in C consisting of integral constants identified by programmer-assigned names. It enhances code readability and maintainability.

    enum Day { SUNDAY = 1, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };
    enum Day today = FRIDAY; // today has integer value 6
    

    2. Call by Value vs Call by Reference:

    Aspect Call by Value Call by Reference
    Argument Passing Passes a copy of actual arguments. Passes the memory addresses of actual arguments.
    Modification Changes made in formal parameters do not affect actual variables in the calling function. Changes made via pointers directly modify original variables in caller.
    Syntax Normal variable identifiers: void fn(int x) Pointer parameters: void fn(int *x)
    Memory Overhead Duplicates values on stack; slower for large structs. Only passes pointer/address; highly memory efficient.

    3. C Program: Swap Two Floating-Point Numbers Using Call by Reference

    #include <stdio.h>
    
    // Function prototype: expects pointer to two float variables
    void swapFloats(float *a, float *b);
    
    int main() {
        float x, y;
    
        printf("=== Swap Two Floats (Call by Reference) ===\n");
        printf("Enter first float number (x): ");
        scanf("%f", &x);
        printf("Enter second float number (y): ");
        scanf("%f", &y);
    
        printf("\nBefore Swapping: x = %.2f, y = %.2f\n", x, y);
    
        // Pass memory addresses using address-of operator (&)
        swapFloats(&x, &y);
    
        printf("After Swapping : x = %.2f, y = %.2f\n", x, y);
    
        return 0;
    }
    
    // Function definition using dereference operator (*)
    void swapFloats(float *a, float *b) {
        float temp;
        temp = *a; // Store value at address 'a' into temp
        *a = *b;   // Assign value at address 'b' to address 'a'
        *b = temp; // Assign temp value to address 'b'
    }
    
  22. Create a structure that can hold the information of Book with bookID, title and price. Read and store N books in “book.dat” from the user. Display the title of the books having price<1000.

    [10]
    View model solution

    Program: Store N Books in File and Filter by Price < 1000

    #include <stdio.h>
    #include <stdlib.h>
    
    // Structure definition for Book
    struct Book {
        int bookID;
        char title[100];
        float price;
    };
    
    int main() {
        int n, i;
        FILE *fp;
        struct Book b;
    
        printf("=== Book Inventory File Manager ===\n");
        printf("Enter the number of books (N): ");
        if (scanf("%d", &n) != 1 || n <= 0) {
            printf("Invalid count!\n");
            return 1;
        }
    
        // Step 1: Open file in write binary mode to store records
        fp = fopen("book.dat", "wb");
        if (fp == NULL) {
            printf("Error creating file book.dat!\n");
            return 1;
        }
    
        printf("\n--- Enter Details of %d Books ---\n", n);
        for (i = 0; i < n; i++) {
            printf("\nBook #%d:\n", i + 1);
            printf("  Book ID: ");
            scanf("%d", &b.bookID);
            getchar(); // consume trailing newline
    
            printf("  Title: ");
            fgets(b.title, sizeof(b.title), stdin);
            // Remove trailing newline
            int len = 0;
            while (b.title[len] != '\0') {
                if (b.title[len] == '\n') {
                    b.title[len] = '\0';
                    break;
                }
                len++;
            }
    
            printf("  Price: ");
            scanf("%f", &b.price);
    
            // Write structure record to binary file
            fwrite(&b, sizeof(struct Book), 1, fp);
        }
        fclose(fp);
        printf("\nAll %d records saved to 'book.dat' successfully.\n", n);
    
        // Step 2: Read from file and display books with price < 1000
        fp = fopen("book.dat", "rb");
        if (fp == NULL) {
            printf("Error opening book.dat for reading!\n");
            return 1;
        }
    
        printf("\n=======================================================\n");
        printf("Books with Price < 1000:\n");
        printf("=======================================================\n");
        int count = 0;
        while (fread(&b, sizeof(struct Book), 1, fp) == 1) {
            if (b.price < 1000.0) {
                printf("ID: %-5d | Price: Rs. %-8.2f | Title: %s\n", b.bookID, b.price, b.title);
                count++;
            }
        }
    
        if (count == 0) {
            printf("No books found with price less than 1000.\n");
        }
        printf("=======================================================\n");
    
        fclose(fp);
        return 0;
    }
    

    Explanation:

    1. struct Book groups bookID, title, and price.
    2. Binary I/O (fwrite and fread) is used with "wb" and "rb" modes for fast, uncorrupted record serialization.
    3. fread() reads one complete struct Book at a time until end-of-file, evaluating b.price < 1000.0.