Skip to main content

C-Programming (BCA-202) - 2019

 




Section-A: Very Short Answer Type Questions

1. What are three-dimensional arrays? How can you initialize them?

A three-dimensional array is a data structure in programming that allows the storage and manipulation of elements in three dimensions. Essentially, it is an array of arrays, where each element is itself a two-dimensional array. These arrays are particularly useful for applications like storing matrices in a sequence, representing a 3D grid, or handling multi-layered data.

Representation of a Three-Dimensional Array

A three-dimensional array can be represented as:

int array[x][y][z];

Here:

  • x represents the number of 2D arrays.
  • y represents the number of rows in each 2D array.
  • z represents the number of columns in each row.

For example:

int array[2][3][4];

This defines an array that contains 2 blocks, each with 3 rows and 4 columns.

Initialization of a 3D Array

A three-dimensional array can be initialized either partially or completely. The values can be explicitly assigned during declaration:

  1. Complete Initialization:
int array[2][2][2] = {
    {{1, 2}, {3, 4}},
    {{5, 6}, {7, 8}}
};

This initializes the 3D array with specific values, structured as nested sets of braces.

  1. Partial Initialization:
int array[2][3][4] = {
    {{1, 2}, {3, 4}},
    {{5, 6}} // Remaining values default to 0
};

When fewer values are provided than the total size, the uninitialized elements are automatically set to 0.

Example Program

Here is a simple program demonstrating the initialization and usage of a 3D array:

#include <stdio.h>

int main() {
    int array[2][2][2] = {
        {{1, 2}, {3, 4}},
        {{5, 6}, {7, 8}}
    };

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < 2; k++) {
                printf("array[%d][%d][%d] = %d\n", i, j, k, array[i][j][k]);
            }
        }
    }

    return 0;
}

This program initializes a 3D array and prints each element with its indices.

Applications of 3D Arrays:

  • Representing multi-layered data such as a Rubik's cube structure.
  • Storing pixel values in image processing.
  • Simulation of three-dimensional space in scientific computations.

2. How is a union different from a structure?

Both unions and structures in C are user-defined data types used to store variables of different types. However, they have distinct functionalities and memory allocation mechanisms.

Key Differences Between Union and Structure

Feature Union Structure
Memory Allocation All members share the same memory location, and the size of a union is equal to the size of its largest member. Each member has a unique memory location, and the size of a structure is the sum of the sizes of all members.
Usage Useful when only one member is used at a time, like in embedded systems or low-level programming. Suitable for representing objects where multiple members may need to store data simultaneously.
Access Modifying one member affects other members, as they share the same memory. Each member is independent, and modifying one does not affect others.

Syntax Example

  1. Union:
union Data {
    int i;
    float f;
    char str[20];
};
  1. Structure:
struct Data {
    int i;
    float f;
    char str[20];
};

Program Demonstrating Differences

#include <stdio.h>

union UnionData {
    int i;
    float f;
};

struct StructData {
    int i;
    float f;
};

int main() {
    union UnionData u;
    struct StructData s;

    u.i = 10;
    u.f = 5.5; // This overwrites u.i because both share memory

    s.i = 10;
    s.f = 5.5; // Both can exist independently in memory

    printf("Union: i = %d, f = %.2f\n", u.i, u.f);
    printf("Structure: i = %d, f = %.2f\n", s.i, s.f);

    return 0;
}

Output:

Union: i = 1092616192, f = 5.50
Structure: i = 10, f = 5.50

This shows that modifying one union member affects others, whereas structure members remain independent.

Applications:

  • Union: Saving memory in applications where only one member is used at a time, like interrupt handlers.
  • Structure: Creating objects or data records where multiple attributes coexist, such as a student database.

3. What do you mean by a dangling pointer?

A dangling pointer is a pointer that points to a memory location that has already been freed or deleted. It occurs when the memory is deallocated while the pointer still holds its address, leading to undefined behavior if accessed.

Causes of Dangling Pointers

  1. Deallocating Memory: When a pointer to dynamically allocated memory is freed using free() or delete but the pointer is not set to NULL.
  2. Returning Local Variables: Returning the address of a local variable from a function causes the pointer to reference a non-existent memory location.
  3. Scope Exiting: Pointers to variables that go out of scope become invalid.

Example of a Dangling Pointer

#include <stdio.h>
#include <stdlib.h>

int* createDanglingPointer() {
    int a = 10;
    return &a; // Address of a local variable is returned
}

int main() {
    int* ptr = (int*)malloc(sizeof(int));
    *ptr = 5;
    free(ptr); // Memory deallocated, ptr is now dangling

    int* dangling = createDanglingPointer();

    return 0;
}

In this example:

  • ptr becomes a dangling pointer after free(ptr).
  • dangling points to invalid memory after the function createDanglingPointer ends.

Preventing Dangling Pointers

  1. Set pointers to NULL after freeing memory:
free(ptr);
ptr = NULL;
  1. Avoid returning local variables from functions.
  2. Use smart pointers in C++ to manage memory safely.

Consequences

Dereferencing a dangling pointer can cause:

  • Crashes.
  • Data corruption.
  • Security vulnerabilities.

Applications: Understanding dangling pointers is critical in developing reliable systems and avoiding memory-related bugs, particularly in low-level programming languages like C and C++.




6. Write a program that will count the number of occurrences of a specified character in a given line of text.

Explanation:

This program takes a line of text and a target character as input, iterates through the text, and counts how many times the character appears.

#include <stdio.h>
#include <string.h>

int main() {
    char text[1000], target;
    int count = 0;

    printf("Enter a line of text: ");
    fgets(text, sizeof(text), stdin);

    printf("Enter the character to count: ");
    scanf("%c", &target);

    for (int i = 0; i < strlen(text); i++) {
        if (text[i] == target) {
            count++;
        }
    }

    printf("The character '%c' appears %d times.\n", target, count);

    return 0;
}

Sample Output:

Enter a line of text: hello world
Enter the character to count: l
The character 'l' appears 3 times.

7. Write a program to pre-multiply a matrix by its transpose.

Explanation:

Matrix transposition involves swapping rows and columns. The program first transposes the matrix and then multiplies it with the original matrix.

#include <stdio.h>

#define SIZE 3

void transpose(int matrix[SIZE][SIZE], int transposed[SIZE][SIZE]) {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            transposed[j][i] = matrix[i][j];
        }
    }
}

void multiply(int a[SIZE][SIZE], int b[SIZE][SIZE], int result[SIZE][SIZE]) {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            result[i][j] = 0;
            for (int k = 0; k < SIZE; k++) {
                result[i][j] += a[i][k] * b[k][j];
            }
        }
    }
}

void printMatrix(int matrix[SIZE][SIZE]) {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int matrix[SIZE][SIZE] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    int transposed[SIZE][SIZE], result[SIZE][SIZE];

    transpose(matrix, transposed);
    multiply(transposed, matrix, result);

    printf("Original Matrix:\n");
    printMatrix(matrix);

    printf("\nTransposed Matrix:\n");
    printMatrix(transposed);

    printf("\nResultant Matrix:\n");
    printMatrix(result);

    return 0;
}

Sample Output:

Original Matrix:
1 2 3
4 5 6
7 8 9

Transposed Matrix:
1 4 7
2 5 8
3 6 9

Resultant Matrix:
66 78 90
78 93 108
90 108 126

8. Design a structure named student to store data about a student which contains the following data elements:

  • Roll No. (int)
  • Name (char array)
  • College (char array)
  • Score (float)

Write a program to input the data about students and output the stored data according to their merit.

Explanation:

The program uses a structure to store student data. It sorts students based on their scores in descending order.

#include <stdio.h>
#include <string.h>

#define MAX_STUDENTS 100

struct Student {
    int rollNo;
    char name[50];
    char college[50];
    float score;
};

void sortStudents(struct Student students[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (students[i].score < students[j].score) {
                struct Student temp = students[i];
                students[i] = students[j];
                students[j] = temp;
            }
        }
    }
}

int main() {
    struct Student students[MAX_STUDENTS];
    int n;

    printf("Enter the number of students: ");
    scanf("%d", &n);

    for (int i = 0; i < n; i++) {
        printf("Enter details for student %d:\n", i + 1);
        printf("Roll No.: ");
        scanf("%d", &students[i].rollNo);
        printf("Name: ");
        scanf(" %[^\n]", students[i].name);
        printf("College: ");
        scanf(" %[^\n]", students[i].college);
        printf("Score: ");
        scanf("%f", &students[i].score);
    }

    sortStudents(students, n);

    printf("\nStudent Details Sorted by Merit:\n");
    for (int i = 0; i < n; i++) {
        printf("Rank %d:\n", i + 1);
        printf("Roll No.: %d\n", students[i].rollNo);
        printf("Name: %s\n", students[i].name);
        printf("College: %s\n", students[i].college);
        printf("Score: %.2f\n\n", students[i].score);
    }

    return 0;
}

Sample Output:

Enter the number of students: 3
Enter details for student 1:
Roll No.: 1
Name: Alice
College: ABC College
Score: 85.5
Enter details for student 2:
Roll No.: 2
Name: Bob
College: XYZ College
Score: 92.3
Enter details for student 3:
Roll No.: 3
Name: Charlie
College: ABC College
Score: 78.4

Student Details Sorted by Merit:
Rank 1:
Roll No.: 2
Name: Bob
College: XYZ College
Score: 92.30

Rank 2:
Roll No.: 1
Name: Alice
College: ABC College
Score: 85.50

Rank 3:
Roll No.: 3
Name: Charlie
College: ABC College
Score: 78.40



9(i). How is a multidimensional array defined in terms of an array pointer? What does each pointer represent? How does this definition differ from a pointer to a collection of contiguous arrays of lower dimensionality?

Explanation of Multidimensional Arrays and Pointers:

A multidimensional array is essentially an array of arrays. It can be defined in terms of pointers, where each pointer represents a level of indirection in accessing elements.

Example of a 2D Array:

Consider a 2D array:

int arr[3][4];

Here:

  • arr is the name of the array and points to the first row.
  • Each row is an array of 4 integers.

Representation Using Pointers:

  1. A 2D array can be accessed using a pointer to an array of integers:
    int (*ptr)[4] = arr;  // Pointer to an array of 4 integers
    
  2. The ptr points to the first row of the array, and you can iterate through rows and columns using pointer arithmetic.

Difference from Contiguous Arrays:

If we use a pointer to a collection of arrays, we work with dynamically allocated memory instead:

int **ptr = (int **)malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++) {
    ptr[i] = (int *)malloc(cols * sizeof(int));
}

Here:

  • ptr is a pointer to an array of pointers.
  • Each pointer in the array dynamically allocates a 1D array.
  • This allows flexibility in the number of rows and columns but requires manual memory management.

9(ii). What is meant by dynamic memory allocation?

Dynamic memory allocation allows a program to request memory at runtime using functions provided by the <stdlib.h> library, such as malloc, calloc, realloc, and free.

Key Points:

  1. malloc: Allocates a specified number of bytes and returns a pointer to the allocated memory. The memory is uninitialized.
    int *ptr = (int *)malloc(10 * sizeof(int));  // Allocates memory for 10 integers
    
  2. calloc: Allocates memory for an array of elements, initializing all bytes to zero.
    int *ptr = (int *)calloc(10, sizeof(int));  // Allocates and initializes memory
    
  3. realloc: Resizes previously allocated memory.
    ptr = (int *)realloc(ptr, 20 * sizeof(int));  // Resizes to hold 20 integers
    
  4. free: Deallocates memory allocated by the above functions.
    free(ptr);  // Releases allocated memory
    

Why Use Dynamic Memory Allocation?

  • Flexibility: Useful when the size of an array or structure is not known at compile time.
  • Efficient Memory Usage: Avoids allocating unused memory.

Library Function Information:

  • malloc and calloc return a pointer to the first byte of allocated memory or NULL if allocation fails.
  • Example:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int *arr;
        int n;
    
        printf("Enter size of array: ");
        scanf("%d", &n);
    
        arr = (int *)malloc(n * sizeof(int));
        if (arr == NULL) {
            printf("Memory allocation failed.\n");
            return 1;
        }
    
        for (int i = 0; i < n; i++) {
            arr[i] = i + 1;
        }
    
        printf("Array elements: ");
        for (int i = 0; i < n; i++) {
            printf("%d ", arr[i]);
        }
    
        free(arr);
        return 0;
    }
    

10(i). Write short notes on the following:

1. strlen()

  • Defined in <string.h>.
  • Returns the length of a null-terminated string (excluding the null character).
  • Example:
    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char str[] = "Hello";
        printf("Length of string: %lu\n", strlen(str));  // Output: 5
        return 0;
    }
    

2. strcpy()

  • Copies the content of one string to another.
  • Syntax: char *strcpy(char *dest, const char *src);
  • Example:
    char str1[20], str2[20] = "World";
    strcpy(str1, str2);
    printf("Copied string: %s\n", str1);  // Output: World
    

3. strcat()

  • Appends the content of one string to the end of another.
  • Syntax: char *strcat(char *dest, const char *src);
  • Example:
    char str1[20] = "Hello, ";
    char str2[] = "World!";
    strcat(str1, str2);
    printf("Concatenated string: %s\n", str1);  // Output: Hello, World!
    

4. strcmp()

  • Compares two strings lexicographically.
  • Syntax: int strcmp(const char *str1, const char *str2);
    • Returns 0 if strings are equal.
    • Returns a positive or negative value based on the comparison.
  • Example:
    char str1[] = "abc", str2[] = "abd";
    printf("Comparison result: %d\n", strcmp(str1, str2));  // Output: -1
    

10(ii). What are the important points to be considered when implementing bit-fields in structures?

A bit-field is a way to allocate specific numbers of bits for variables within a structure, commonly used for memory-efficient programming.

Key Points:

  1. Definition: Bit-fields are defined using a colon and the number of bits.

    struct Flags {
        unsigned int isOn : 1;    // 1 bit
        unsigned int value : 3;  // 3 bits
    };
    
  2. Purpose:

    • Save memory in embedded systems or hardware programming.
    • Control low-level data directly.
  3. Limitations:

    • Bit-fields cannot have pointers.
    • Memory alignment may vary across systems.
    • Bit-fields cannot be taken the address of (& operator).
  4. Example:

    #include <stdio.h>
    
    struct Flags {
        unsigned int isOn : 1;
        unsigned int value : 3;
    };
    
    int main() {
        struct Flags f = {1, 5};
        printf("isOn: %d, value: %d\n", f.isOn, f.value);  // Output: isOn: 1, value: 5
        return 0;
    }
    

11(i). Describe two different approaches to unloading a data file. Which approach is better and why? For what kinds of applications are unformatted data files well-suited?

Unloading a Data File:

Unloading a data file means transferring its content to another medium or format for analysis, backup, or further processing. Two common approaches are:

1. Formatted File Unloading:

  • Description:
    • Data is written in human-readable formats (e.g., .txt or .csv).
    • Uses functions like fprintf() or fputs() to write data.
    • Suitable for files intended for users or external systems.
  • Advantages:
    • Easy to read and debug.
    • Compatible with external tools like Excel or text editors.
  • Disadvantages:
    • Larger file size due to added delimiters, spaces, and line breaks.
    • Parsing requires additional processing for applications.
  • Example:
    FILE *fp = fopen("data.txt", "w");
    int id = 1;
    float score = 95.5;
    fprintf(fp, "ID: %d, Score: %.2f\n", id, score);
    fclose(fp);
    

2. Unformatted (Binary) File Unloading:

  • Description:
    • Data is written in binary format using functions like fwrite().
    • Data is stored as raw bytes, making it compact and efficient.
  • Advantages:
    • Compact storage and faster read/write operations.
    • Directly compatible with memory structures.
  • Disadvantages:
    • Not human-readable.
    • Requires the same data structure to interpret correctly.
  • Example:
    FILE *fp = fopen("data.bin", "wb");
    int id = 1;
    float score = 95.5;
    fwrite(&id, sizeof(int), 1, fp);
    fwrite(&score, sizeof(float), 1, fp);
    fclose(fp);
    

Which is Better?

  • Formatted Files are better for portability and user understanding.
  • Unformatted Files are better for performance, especially in applications involving large datasets like machine learning or database management.

Applications of Unformatted Data Files:

  • High-performance computing.
  • Embedded systems.
  • Game development (storing graphics/audio).
  • Applications with strict memory constraints.

11(ii). Write a function using pointers to add two matrices and return the resultant matrix to the calling function.

Explanation:

This program demonstrates matrix addition using pointers. A function takes pointers to two matrices and their dimensions, calculates the sum, and returns the resultant matrix.

#include <stdio.h>
#include <stdlib.h>

int** addMatrices(int **a, int **b, int rows, int cols) {
    int **result = (int **)malloc(rows * sizeof(int *));
    for (int i = 0; i < rows; i++) {
        result[i] = (int *)malloc(cols * sizeof(int));
        for (int j = 0; j < cols; j++) {
            result[i][j] = a[i][j] + b[i][j];
        }
    }
    return result;
}

void printMatrix(int **matrix, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int rows = 2, cols = 2;
    
    int **a = (int **)malloc(rows * sizeof(int *));
    int **b = (int **)malloc(rows * sizeof(int *));
    for (int i = 0; i < rows; i++) {
        a[i] = (int *)malloc(cols * sizeof(int));
        b[i] = (int *)malloc(cols * sizeof(int));
    }
    
    // Initialize matrices
    a[0][0] = 1; a[0][1] = 2;
    a[1][0] = 3; a[1][1] = 4;

    b[0][0] = 5; b[0][1] = 6;
    b[1][0] = 7; b[1][1] = 8;

    printf("Matrix A:\n");
    printMatrix(a, rows, cols);

    printf("\nMatrix B:\n");
    printMatrix(b, rows, cols);

    // Add matrices
    int **result = addMatrices(a, b, rows, cols);

    printf("\nResultant Matrix:\n");
    printMatrix(result, rows, cols);

    // Free memory
    for (int i = 0; i < rows; i++) {
        free(a[i]);
        free(b[i]);
        free(result[i]);
    }
    free(a);
    free(b);
    free(result);

    return 0;
}

Output:

Matrix A:
1 2
3 4

Matrix B:
5 6
7 8

Resultant Matrix:
6 8
10 12

12(i). What is a masking operation? What is the purpose of each operand? Which operand is the mask, and how is it chosen?

Explanation:

A masking operation uses bitwise operations (AND, OR, XOR) to manipulate specific bits in a binary number. The "mask" is a binary value used to enable, disable, or toggle certain bits.

Key Bitwise Operations:

  1. AND (&): Used to clear specific bits (turn bits off).

    int num = 0b10101100;  // Original number
    int mask = 0b11110000;  // Mask to preserve the upper 4 bits
    int result = num & mask;  // Result: 0b10100000
    
  2. OR (|): Used to set specific bits (turn bits on).

    int num = 0b10100000;
    int mask = 0b00001111;  // Mask to set the lower 4 bits
    int result = num | mask;  // Result: 0b10101111
    
  3. XOR (^): Used to toggle specific bits.

    int num = 0b10101100;
    int mask = 0b00001111;  // Mask to toggle the lower 4 bits
    int result = num ^ mask;  // Result: 0b10100011
    

Mask and Purpose:

  • The mask is chosen based on the operation and the bit positions to be manipulated.
  • Example: To extract the 3rd bit of a number:
    int num = 0b10101100;
    int mask = 0b00000100;  // Mask to isolate the 3rd bit
    int result = num & mask;  // Result: 0b00000100 (if the 3rd bit is 1)
    

12(ii). Write macro definitions with arguments for calculating simple interest and amount.

#include <stdio.h>

#define SIMPLE_INTEREST(p, r, t) ((p) * (r) * (t) / 100)
#define AMOUNT(p, si) ((p) + (si))

int main() {
    float principal = 1000.0, rate = 5.0, time = 2.0;

    float si = SIMPLE_INTEREST(principal, rate, time);
    float totalAmount = AMOUNT(principal, si);

    printf("Simple Interest: %.2f\n", si);
    printf("Total Amount: %.2f\n", totalAmount);

    return 0;
}

13(i). What are the differences between Union and Structure?

Overview:

Structures and Unions are user-defined data types in C that allow you to group different types of variables under one name. However, they have significant differences in how memory is allocated and used.


Definition:

  • Structure: A collection of variables (called members) that are grouped together under one name. Each member is allocated separate memory, and all members can be accessed independently.

    • Example:
      struct Student {
          int roll_no;
          char name[20];
          float marks;
      };
      
  • Union: Similar to a structure, but all members share the same memory location. At any given time, only one member can hold a value.

    • Example:
      union Data {
          int i;
          float f;
          char str[20];
      };
      

Key Differences Between Structure and Union:

Feature Structure Union
Memory Allocation Allocates separate memory for each member. All members share the same memory location.
Size Size is the sum of the sizes of all members. Size equals the size of the largest member.
Access All members can store values and be accessed simultaneously. Only one member can store a value at a time. Accessing another member overwrites the previous value.
Use Case Used when all data members need to be stored simultaneously. Used when memory efficiency is critical and only one member is required at a time.
Initialization All members can be initialized simultaneously. Only one member can be initialized at a time.
Purpose Suitable for grouping data where all values are required. Suitable for applications like I/O operations or protocol parsers.

Examples:

Structure Example:

#include <stdio.h>

struct Student {
    int roll_no;
    char name[20];
    float marks;
};

int main() {
    struct Student student = {1, "John Doe", 85.5};
    printf("Roll No: %d\n", student.roll_no);
    printf("Name: %s\n", student.name);
    printf("Marks: %.2f\n", student.marks);
    return 0;
}
  • Memory Allocation:
    • int roll_no: 4 bytes.
    • char name[20]: 20 bytes.
    • float marks: 4 bytes.
    • Total: 28 bytes.

Union Example:

#include <stdio.h>

union Data {
    int i;
    float f;
    char str[20];
};

int main() {
    union Data data;
    data.i = 10;
    printf("Integer: %d\n", data.i);
    data.f = 220.5;
    printf("Float: %.2f\n", data.f);
    return 0;
}
  • Memory Allocation:
    • int i: 4 bytes.
    • float f: 4 bytes.
    • char str[20]: 20 bytes.
    • Total: 20 bytes (size of the largest member).

Use Cases:

  1. Structure:

    • Grouping related data, like a student's roll number, name, and marks.
    • Database design where each record holds multiple fields.
  2. Union:

    • Situations where only one member is needed at a time:
      • Memory-efficient applications (e.g., embedded systems).
      • Handling multiple data types in the same memory location (e.g., parsing files or packets).

13(ii). Write short notes on the following functions:

1. rewind()

  • Resets the file pointer to the beginning of a file.
  • Equivalent to fseek(fp, 0, SEEK_SET), but simpler to use.
  • Does not return a value.
  • Useful for re-reading a file or resetting the read/write position.

Example:

#include <stdio.h>

int main() {
    FILE *fp = fopen("file.txt", "r");
    if (!fp) {
        printf("Error opening file.\n");
        return 1;
    }

    char c;
    while ((c = fgetc(fp)) != EOF) {
        printf("%c", c);  // Read the file content
    }

    rewind(fp);  // Reset the pointer to the start
    printf("\nReading again:\n");

    while ((c = fgetc(fp)) != EOF) {
        printf("%c", c);  // Read the file again
    }

    fclose(fp);
    return 0;
}

2. fseek()

  • Moves the file pointer to a specified position within the file.
  • Syntax: fseek(FILE *fp, long offset, int whence)
    • offset: Number of bytes to move the pointer.
    • whence: Starting position (can be SEEK_SET, SEEK_CUR, or SEEK_END).

Example:

#include <stdio.h>

int main() {
    FILE *fp = fopen("file.txt", "r");
    if (!fp) {
        printf("Error opening file.\n");
        return 1;
    }

    fseek(fp, 5, SEEK_SET);  // Move to the 5th byte from the start
    char c = fgetc(fp);
    printf("Character at position 5: %c\n", c);

    fclose(fp);
    return 0;
}

3. feof()

  • Checks if the end-of-file (EOF) has been reached.
  • Returns a non-zero value if EOF is reached, otherwise 0.
  • Typically used in loops to read data until EOF.

Example:

#include <stdio.h>

int main() {
    FILE *fp = fopen("file.txt", "r");
    if (!fp) {
        printf("Error opening file.\n");
        return 1;
    }

    while (!feof(fp)) {
        char c = fgetc(fp);
        if (c != EOF) {
            printf("%c", c);
        }
    }

    fclose(fp);
    return 0;
}

4. fscanf()

  • Reads formatted input from a file, similar to scanf().
  • Syntax: fscanf(FILE *fp, const char *format, ...).
  • Commonly used to read structured data like integers, floats, or strings.

Example:

#include <stdio.h>

int main() {
    FILE *fp = fopen("data.txt", "r");
    if (!fp) {
        printf("Error opening file.\n");
        return 1;
    }

    int id;
    float score;
    char name[20];

    while (fscanf(fp, "%d %s %f", &id, name, &score) == 3) {
        printf("ID: %d, Name: %s, Score: %.2f\n", id, name, score);
    }

    fclose(fp);
    return 0;
}

Sample Input (data.txt):

1 John 85.5
2 Alice 90.0

Output:

ID: 1, Name: John, Score: 85.50
ID: 2, Name: Alice, Score: 90.00


Comments

Popular posts from this blog

C PROGRAMING 202 - 2023

1. Write various data types supported in C with examples. Introduction: In C programming, data types specify the type of data that a variable can hold. They are essential for defining variables and managing memory efficiently. Types of Data Types in C: C supports the following primary data types: Basic Data Types : int : Used for integers (whole numbers). Example: int age = 25; float : Used for single-precision floating-point numbers. Example: float height = 5.8; double : Used for double-precision floating-point numbers. Example: double pi = 3.14159; char : Used for characters. Example: char grade = 'A'; Derived Data Types : Array : A collection of elements of the same type. Example: int marks[5] = {90, 85, 78, 92, 88}; Pointer : Stores the address of another variable. Example: int *p; p = &age; Structure : A user-defined data type to group related variables. Example: struct Student { int id; char name[50]; float marks; }; Enumeratio...

Digital Electronics and Computer Organisation.2021

Section A : 1. Prove that NOR and NAND gates are universal gates. Definition of Universal Gates : Universal gates are those which can be used to implement any Boolean function without needing any other gate types. Proof : NAND Gate : A NAND gate can be used to create the basic gates: NOT Gate : Input A A to both inputs of the NAND gate: Output = A ⋅ A = A ′ \text{Output} = A \cdot A = A' AND Gate : Combine NOT gates and NAND gates: ( A ⋅ B ) ′ ⋅ ( A ⋅ B ) ′ = A ⋅ B (A \cdot B)' \cdot (A \cdot B)' = A \cdot B . OR Gate : Using De Morgan's theorem and NOT gates: A ′ ⋅ B ′ = ( A + B ) ′ A' \cdot B' = (A + B)' . NOR Gate : Similarly, NOR gates can be used to create: NOT Gate : Input A A to both inputs of the NOR gate: Output = ( A + A ) ′ = A ′ \text{Output} = (A + A)' = A' OR Gate : Combine two NOT gates and NOR gates: ( A + B ) ′ + ( A + B ) ′ = A + B (A + B)' + (A + B)' = A + B . AND Gate : Using De Morgan...
Answer 1: What is a real-time operating system? A Real-Time Operating System (RTOS) is an operating system that processes data and events within a guaranteed time frame . It is designed to handle real-time tasks where timely execution is crucial. There are two types: Hard Real-Time OS – Strict deadlines must be met (e.g., pacemakers, aircraft systems). Soft Real-Time OS – Deadlines are important but not critical (e.g., video streaming). RTOS is used in embedded  systems , robotics, and industrial control systems. Great! Here's a detailed and unrestricted explanation of hard and soft semaphores : Answer 2: What is a Hard and Soft Semaphore? A semaphore is a synchronization mechanism used in operating systems and concurrent programming to control access to shared resources and avoid issues like race conditions and deadlocks. Semaphores help coordinate multiple processes or threads trying to access critical sections of code or shared data. There are two main types of ...