0% found this document useful (0 votes)
6 views

C-1

The document presents a project report on the EduQuiz System, a C-based console application designed to enhance user engagement through interactive quizzes and provide a secure management interface for administrators. It outlines the project's objectives, features, limitations, and technical implementation, emphasizing the use of C programming principles such as file handling and multithreading. The report also acknowledges the support received from instructors and peers during the development process.

Uploaded by

janakbhatta898
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

C-1

The document presents a project report on the EduQuiz System, a C-based console application designed to enhance user engagement through interactive quizzes and provide a secure management interface for administrators. It outlines the project's objectives, features, limitations, and technical implementation, emphasizing the use of C programming principles such as file handling and multithreading. The report also acknowledges the support received from instructors and peers during the development process.

Uploaded by

janakbhatta898
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 53

`

TRIBHUVAN UNIVERSITY
INSTITUTE OF ENGINNERING
PULCHOWK CAMPUS
PROJECT REPORT ON
EDUQUIZ SYSTEM

SUBMITTED BY:
SUBMITTED TO:
HIMANSHU CHAND(081BCT034)
DEPARTMENT OF
ISHAN GAUTAM(081BCT035) ELECTRONICS
AND
JANAK BHATTA(081BCT036) COMPUTER
ENGINEERING

2|Page
ACKNOWLEDGEMENT
We would like to express our sincere gratitude to our instructor Santosh
Giri for providing us with guidance and encouragement throughout this
project. We also extend our appreciation to the Institute of Engineering,
Pulchowk Campus, for offering the necessary resources and environment
to complete this project.

Additionally, we thank our friends and family for their unwavering support
and motivation, which played a crucial role in the successful completion of
this project.
Lastly, we express our gratitude to the countless authors, researchers, and
professionals whose work served as a foundation for our project. Their
contributions have been instrumental in shaping our understanding and
approach to the subject matter.

This project would not have been possible without the support,
guidance, and inspiration of all those mentioned above.

Sincerely,
Himanshu Chand
Ishan Gautam
Janak Bhatta

i|Page
TABLE OF CONTENTS

S.N TITLE Page Number


.
1. Acknowledgement i
Abstract ii
Introduction 1
Background and Problem Statements 1
Objectives 1
Features 1
Limitations 2
Problem Analysis 2
Theory Overview 2
Standard C Library Functions
Main Algorithm
User Authentication Functions
Menu Functions
Question Management Functions
Quiz Gameplay Functions
Time-Limiged Answer
System(Countdown Timer)
File Handling Functions
Score Management Functions
Utility Functions
Algorithm 1:Quiz Platform Main
Algorithm
Algorithm 2: Admin Authentication
Algorithm
Algorithm 3: Add Questions Algorithm
Algorithm 4: Start Quiz Algorithm
Algorithm 5: Countdown Timer
Algorithm

ii | P a g e
Algorithm 6: Input Validation
Algorithm
Algorithm 7: Question File Handling
Algorithm
Algorithm 8: Quiz Score Calculation
Algorithm

iii | P a g e
ABSTRACT
The Quiz Game System is a C-based console application designed to
provide an interactive quiz experience for players and a secure
management interface for administrators. Developed as part of a practical
exploration of C programming, it aims to enhance user engagement
through timed gameplay while offering a platform for administrators to
update content. This dual-purpose tool reflects its educational intent,
fostering both technical skill development and knowledge assessment
within a campus environment.

The system leverages key C programming features to ensure robust


functionality and an efficient user experience. File handling enables
persistent storage of quiz questions in a binary format, while
multithreading implements a real-time countdown timer, limiting each
answer to 20 seconds for fair and dynamic gameplay. Structured
programming principles underpin its design, with separate modules for
player interaction and admin access, the latter secured by a password-
protected authentication mechanism to maintain data integrity.

By blending technical precision with practical utility, the Quiz Game


System demonstrates C’s versatility in building educational applications.
Players benefit from immediate feedback and a competitive quiz format,
while administrators enjoy flexibility in managing question sets. This
project not only showcases the power of low-level programming but also
serves as a scalable foundation for future enhancements, such as
expanded question types or cross-platform compatibility, enriching its
potential impact in academic settings.

iv | P a g e
v|Page
INTRODUCTION
1. Background and Problem Statements:
The growing emphasis on interactive learning tools and engaging
educational experiences has spurred the need for innovative software
solutions in academic settings. To address this, we developed the Quiz
Game System using the C programming language, aiming to create a
structured, real-time quiz platform that captivates players while
integrating essential programming concepts. The system targets both
entertainment and education, offering a dynamic alternative to traditional,
static quiz methods that often lack immediacy and interactivity.

This project was undertaken as part of our C Programming coursework


during the first year of the Computer Engineering program at Tribhuvan
University’s Institute of Engineering, Pulchowk Campus. It provided an
opportunity to translate theoretical knowledge—such as file handling for
data persistence, multithreading for time management, and authentication
for secure access—into a practical application. By tackling challenges like
timer synchronization and user input validation, we honed our technical
skills and explored C’s potential in real-world scenarios.

The development process involved dividing the system into distinct


modules—quiz gameplay, admin question management, and time
enforcement—distributing responsibilities among team members for
efficient collaboration. With guidance from our instructor, Prof. Santosh
Giri, and supplemental resources, we ensured the system’s stability and
documented our efforts. This project underscores the value of applying
structured programming to solve practical problems, enhancing both
learning and engagement.

2. Objectives:
 To enhance logical reasoning and problem-solving skills through C
programming.
 To apply theoretical knowledge of C in a real-world application.
 To develop a mini database system for storing quiz questions using
file handling.
 To foster teamwork and task division among group members.

1|Page
 To simplify complex problems, such as time management, using C
constructs.
3. Features:
The Interactive Quiz System includes the following features to ensure
efficiency and usability:
 Password-protected admin module for adding questions.
 Timed quiz gameplay with a 20-second limit per question,
implemented using threading.
 File handling for persistent storage of questions in a binary file.
 Real-time scoring and feedback during quiz play.
4. Limitations:

 This program consists of some library header files which were


not discussed in the classroom.
 The system currently supports only text-based input and output.
 The countdown timer cannot be paused once started.

PROBLEM ANALYSIS
1. Understanding the problem:
Our team aimed to create a reliable, interactive quiz system. We decided
to use C’s file handling for data persistence, threading for time limits, and
string operations for user interaction, ensuring a professional and
engaging application.
2. Feasibility:
The project required foundational C programming skills, teamwork, and
logical reasoning. Time management was critical amidst regular
coursework. We ensured feasibility by leveraging classroom knowledge
and supplementing it with online resources.
3. Input requirements:
Users input menu choices (1-3), admin passwords, quiz answers (1-4), and
question details (text and correct options). The system must handle these
inputs robustly.
4. Processing Requirements:

2|Page
A 32-bit or higher OS is needed, with support for threading (Windows-
specific in this case). The system processes inputs, manages timers, and
updates files without crashing on invalid inputs.
5. Output Requirements:
Outputs include menu prompts, quiz questions with options, real-time
timer updates, and final scores, all displayed clearly on the screen.

THEORY OVERVIEW
C is a general-purpose, procedural programming language developed by
Dennis Ritchie at Bell Labs in the early 1970s. Renowned for its efficiency,
portability, and ability to access low-level memory through pointers, C is
extensively utilized in system programming, embedded systems, and
performance-critical applications. It has significantly influenced modern
languages such as C++, C#, and Objective-C, offering a balance between
high-level abstraction and low-level control. However, C lacks modern
safety features like automatic memory management, placing the burden
on programmers to manage resources meticulously. This section explores
essential C concepts, including preprocessor directives, input/output,
control statements, functions, arrays, strings, structures, pointers, and file
handling, providing a foundation for understanding its theory and
application. These concepts are exemplified in practical contexts, such as
the library management system header (headers.h) provided, which uses
structures, pointers, and standard library functions to manage users,
books, and transactions.
1. Preprocessor Directives:
Preprocessor directives are instructions beginning with the # symbol,
executed before the compilation process begins. They modify the source
code by including external files, defining constants, or enabling conditional
compilation.
#include: Incorporates external files into the program. For
instance,#include<stdio.h> includes the standard input/output library,
providing access to functions like printf and scanf.
#define: Defines macros, which can represent constants or expressions.
For example, #define PI 3.14159 creates a constant, while #define
SQUARE(x) ((x) * (x)) defines a macro to compute the square of a value.
#ifdef, #ifndef, #endif: Facilitate conditional compilation, allowing code
blocks to be included or excluded based on whether a macro is defined.
Example:
#define VALUE 10

3|Page
#include<stdio.h>
int main{
printf(“value: %d”, VALUE);
return 0;
}
In this code, the preprocessor replaces VALUE with 10 before compilation,
and stdio.h provides the printf function to display the value.
2. Input and Output:
Input and output (I/O) operations in C are facilitated by functions from the
stdio.h header, categorized into unformatted and formatted I/O. These
operations enable interaction between the program and external devices,
such as the keyboard (input) and screen (output).
2.1. Unformatted I/O:
Unformatted I/O functions handle raw data without specific formatting,
offering simplicity but limited control.
 getchar():Reads a single character from the standard input (typically
the keyboard) and returns it as an integer value. This function is
useful for character-by-character input processing.
 putchar(ch): Outputs a single character, specified by the variable ch,
to the standard output (typically the screen). It is often used in loops
to display strings character by character.
 puts(str): Writes a string, followed by a newline character (\n), to the
standard output. It is a convenient way to output messages or
prompts.
Example:
#include<stdio.h>
int main{
char ch;
printf(“Enter a character\n”);
ch=getchar();
printf(“You’ve entered\n”);
putchar(ch);
return 0;

4|Page
}
Here, getchar() captures a character entered by the user, putchar(ch)
displays it, and puts adds a message with a newline. This demonstrates
basic unformatted I/O for character and string manipulation. Note that
getchar() returns an integer to accommodate special values like EOF (end-
of-file), which is useful in file operations.

2.2. Formatted I/O:


Formatted I/O functions provide precise control over data presentation
using format specifiers, which define how data is read or displayed. These
functions are particularly useful for handling multiple data types in a
structured manner.
 scanf ("format", &var1, &var2, ...): Reads input from the standard in-
put based on the format string (e.g., %d for integers, %f for floats,
%s for strings) and stores the values in variables. The address-of
operator (&) is used to pass the memory locations of variables,
enabling scanf to modify them directly. For strings (%s), the & is
omitted because the string variable itself is a pointer to the first
character.
 printf("format", var1, var2, ...): Outputs text to the standard out-put,
formatting variables according to the specifiers in the format string
(e.g., %.2f limits a float to two decimal places, %x displays an
integer in hexa-decimal).
Example:
#include <stdio.h>
int main() {
int age;
float height;
char name [50];
printf("Enter age, height, and name: ");
scanf("%d %f %s", &age, &height, name);
printf("Age: %d, Height: %.2f, Name: %s\n", age, height, name);
return 0;
}

5|Page
In this program, scanf reads an integer (age), a float (height), and a string
(name) from the user, using & for age and height to specify their memory
addresses.
For name, no & is needed because name is already a pointer to the array's
first element. printf then displays these values, formatting height to two
decimal places. The format specifiers ensure that the input is parsed
correctly and the output is presented in a readable form. In headers.h,
printf is used for user interaction (e.g., in print header), and scanf may be
used to input user data like username or book_id.
Key Note: Omitting the & in scanf for non-pointer variables can lead to
runtime errors or undefined behavior, as it expects memory addresses
rather than values. Additionally, scanf can fail if the input does not match
the expected format, so robust programs should check its return value (the
number of successfully assigned items).
3. Pointers:
Pointers are variables that store memory addresses, offering powerful
capabilities for direct memory manipulation, dynamic memory allocation,
and efficient data handling. They are a cornerstone of C programming,
enabling low-level control and distinguishing C from higher-level
languages.
3.1. Declaration and Initialization:
A pointer is declared with an asterisk (*) and must point to a specific data
type, ensuring type safety when accessing the data it addresses. It is
initialized with the address of a variable using the address-of operator (&).
 Declaration: int *ptr; declares a pointer to an integer. The asterisk
indi-cates that ptr will hold the address of an integer, not the integer
itself.
 Initialization: int x 10; ptr &x; assigns the address of x to ptr. The &
operator retrieves the memory address of x, which is typically a hex-
adecimal value (e.g., 0x7ffee).
3.2. Dereferencing:
Dereferencing a pointer with the asterisk (*) accesses the value stored at
the address it points to, allowing both reading and writing of the data.
 Dereference: *ptr retrieves or modifies the value of x (e.g., reading
yields 10, writing *ptr = 20 changes x to 20).
Example:
#include <stdio.h>

6|Page
int main() {
int x 10; int *ptr &x; printf(" Address of x: %p\n", (void*)ptr);
printf("Value of x via pointer: %d\n", *ptr);
*ptr 20; // Modify x via pointer
printf("New value of x: %d\n", x);
return 0;
}
Here, ptr holds the memory address of x, displayed using the %p specifier
(with a cast to void* to ensure portability). Dereferencing *ptr yields the
value 10, and assigning *ptr 20 updates x, illustrating how pointers
provide indirect access to data. The output shows the address, the initial
value, and the modified value, demonstrating pointer manipulation.
3.3. Pointer Arithmetic:
Pointers can be incremented or decremented to navigate memory
locations, with the offset scaled by the size of the data type (e.g., 4 bytes
for an integer on most systems). This is particularly useful for array
traversal, where array elements are stored contiguously.
 Increment: ptr + 1 moves the pointer to the next integer's memory
loca-tion, adding 4 bytes to the address if int is 4 bytes.
 Decrement: ptr 1 moves it backward similarly.
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
int *ptrarr; // Points to arr[0]
for (int i=0; i < 3; i++) {
printf("%d", *ptr);
ptr++; // Moves to the next integer
return 0;
}
In this array example, ptr initially points to arr[0]. Each ptr++ advances it
to the next element, printing 10, 20, and 30. This demonstrates pointer
arithmetic in traversing arrays, where the array name arr acts as a pointer
to its first element. Pointer arithmetic is scaled automatically by the

7|Page
compiler, so ptr++ adds the size of int, not just 1 byte, ensuring correct
alignment with data elements.
3.4. Pointers in Function:
Pointers enable pass-by-reference, allowing functions to modify the
original vari-ables passed to them, unlike pass-by-value, where only copies
are modified. This is achieved by passing the addresses of variables, which
the function dereferences to access and alter the original data.
 Function Definition: void swap(int *a, int *b) { int temp =* a ; *a *b: *
b = temp; }
 Function Call: swap(&x, &y); passes the addresses of x and y.
Example:
#include <stdio.h>
void swap(int *a, int b) {
int temp *a;
* a =*b;
* b = temp;
}
int main() {
int x = 5 , y = 10;
printf(" Before swap: x =\%d, y =\%d backslash n^ prime prime ,x,y) ;
swap(&x, &y);
printf(" After swap: x =\%d y =\%d backslash n^ " ,x,y) // Outputs: x: 10,
y:5
return 0;
}
The swap function uses pointers to exchange the values of x and y by
accessing and modifying their memory locations directly. Without pointers,
swap would only modify local copies, leaving x and y unchanged. This
example highlights the power of pointers in enabling efficient, direct data
manipulation. In headers.h, pointers to structures (e.g., User *user in
authenticate_user) allow functions to modify user data directly.
3.5. Dynamic memory allocation:

8|Page
Pointers facilitate runtime memory allocation using functions from stdlib.h,
such as malloc, calloc, and realloc. These functions allocate memory
dynamically, allowing programs to adapt to variable data sizes, unlike
static arrays with fixed sizes.
 Allocation: int *p= malloc(sizeof(int) * 5); allocates memory for 5
integers and returns a pointer to the first byte. malloc does not
initialize the memory, so it may contain garbage values.
 Initialization: int *p = calloc(5, sizeof(int)); allocates and initializes
the memory to zero.
 Reallocation: p= realloc(p, sizeof(int) 10); resizes the memory block,
preserving existing data if possible.
 Deallocation: free(p); releases the memory, preventing leaks.
#include <stdio.h>
#include <stdlib.h>
int main() {
int * p = malloc(sizeof(int) * 3); printf ("Memory allocation failed\n");
if (p NULL) {
return 1;
} for (int i = 0 i < 3 i++) {
p[i] = i + 1;
}
for (int i = 0 ; i < 3 i++) {
printf("%d", p[i]);
}
free (p);
return 0;
}
This program allocates memory for 3 integers, initializes them, prints them
(1, 2, 3), and frees the memory. The if (p== NULL) check ensures
robustness, as malloc returns NULL if allocation fails (e.g., due to
insufficient memory). The sizeof operator is used here to determine the
size of int, ensuring portable memory allocation.

9|Page
Key Point: Always free dynamically allocated memory when it is no longer
needed to avoid memory leaks, a common issue in C programming where
allocated memory is not released, leading to resource exhaustion over
time.

4. Control Statements:
Control statements direct the flow of execution through decision-making
and repetition, allowing programs to make choices or repeat actions based
on conditions.
4.1. Selective Structures:
Selective structures evaluate conditions to determine which code block to
execute.
 if: Executes code if a condition is true. For example, if (x > 0) printf
("Positive"); checks if x is positive and prints a message if true.
 if-else: Provides an alternative for false conditions. For example, else
printf("Non-positive"); prints a message if x is not positive.
 if-else-if: Handles multiple conditions. For example, if (x > 0)
printf("Positive"); else if (x < 0) printf("Negative"); else printf("Zero");
categorizes x as positive, negative, or zero.
4.2. Looping Structures:
Looping structures repeat a block of code until a condition is met or for a
specified number of iterations.
 for: Executes a fixed number of iterations, typically using a loop
counter. For example, for (int i = 0 i < 5 i++) loops 5 times,
incrementing i from 0 to 4.
 while: Repeats while a condition is true, checking the condition
before each iteration. For example, while (i < 5) continues as long as
i is less than 5.
 do-while: Similar to while, but ensures at least one execution by
checking the condition after each iteration. For example, do {...}
while (i < 5); executes the block at least once.
Example:
#include <stdio.h>
int main() {
for (int i=0; i<10; i++) {

10 | P a g e
if (i==5) break; // Exits loop at 5
printf("%d", i);
}
return 0;
}
This loop prints 0 to 4, terminating early with break when i equals 5. The
break statement is useful for exiting loops prematurely based on a
condition, such as finding a specific value in a search.
5. Functions:
Functions modularize code, enhancing reusability and organization. Every
C program starts execution with the main function, and additional
functions can be defined to perform specific tasks. Functions consist of a
declaration, definition, and call.
 Declaration: Specifies the function's interface, including its return
type, name, and parameters. For example, int add(int a, int b);
declares a function that returns an integer and takes two integer
parameters.
 Definition: Implements the function's logic. For example, int add(int
a, int b) { return a+b; } defines the add function to return the sum of
its parameters.
 Call: Invokes the function, passing arguments. For example, add (3,
4); calls add with 3 and 4, returning 7.
Functions can be categorized as library functions (predefined in standard
libraries) or user-defined functions (created by the programmer). They
support pass-by-value (where arguments are copied) and pass-by-
reference (using pointers, as dis-cussed earlier). In headers.h, function
prototypes void AddQuestions() and void CheckPassword() declare user-
defined functions for adding questions and checking password
respectively.
Example (Recursion):
#include <stdio.h>
int factorial (int n) {
if (n <= 1) return 1; // Base case
return n*factorial (n-1); // Recursive call
}

11 | P a g e
int main() {
printf("Factorial of 5: %d\n", factorial (5)); // Outputs: 120
return 0;
}
This recursive function computes 5! (5 x 4 x 3 x 2 x1=120). Recursion
involves a function calling itself with a modified parameter until a base
case is reached, here n <= 1. Recursive functions are powerful for
problems with a recursive structure, like factorials or tree traversals, but
require careful design to avoid infinite recursion or stack overflow.
6. Arrays:
Arrays store elements of the same type in contiguous memory locations,
accessed by zero-based indices. They are useful for managing collections
of data, such as lists of numbers or characters.
 Declaration: int arr [5] = {1, 2, 3, 4, 5); declares an array of 5
integers, initializing it with values. Uninitialized elements are set to 0
if the array is partially initialized, or contain garbage values if not
initialized at all.
 Access: arr[0] retrieves the first element (1), arr[1] the second (2),
and so on. Indices range from 0 to size-1, and accessing beyond
these bounds causes undefined behavior, a common source of bugs
in C.
Arrays can be multidimensional, such as two-dimensional arrays for
matrices (e.g., int matrix [3] [4];). In headers.h, arrays are used within
structures (e.g., char option), defining fixed-size buffers for strings like
questions and options.
Example:
#include <stdio.h>
int main() {
int arr [3] {10, 20, 30};
for (int i=0; i < 3; i++) {
printf("%d", arr[i]);
}
return 0;
}

12 | P a g e
This program prints 10, 20, and 30, iterating over the array using a for
loop. The array name arr is a pointer to its first element, enabling pointer
arithmetic as shown in the pointers section.
7. Strings and Manipulation:
Strings in C are character arrays terminated by a null character (10), which
marks the end of the string. They are manipulated using functions from
the string.h header, providing operations like copying, concatenation, and
comparison.
 Declaration: char str[10]= "Hello"; declares a string with space for 10
characters, including the 0. The string "Hello" occupies 6 bytes (5
letters + \0).
 Manipulation Functions:
- strcpy(dest, src): Copies the string src (including (0) to dest. The
destination must have enough space, or a buffer overflow occurs.
- strcat (dest, src): Concatenates src to the end of dest, overwriting
dest's 0 and adding a new one.
- strlen(str): Returns the length of str, excluding 0.
- strcmp(str1, str2): Compares str1 and str2 lexicographically, re-
turning 0 if equal, a negative value if str1 < str2, and a positive
value if str1> str2.
Example:
#include <stdio.h>
include <string.h> #
int main() {
char str[20];
strcpy(str, "Hello");
printf("Length: %zu\n", strlen(str)); // Outputs: 5
strcat(str, "World");
printf("Concatenated: %s\n", str); // Outputs: Hello World
return 0;
}
This program copies "Hello" into str, prints its length (5), and appends"
World", demonstrating string manipulation. Note that str must be large

13 | P a g e
enough to hold the concatenated result (11 characters, including (\0), or
undefined behavior occurs.
8. Structures:
Structures group variables of different types under a single name, useful
for repre-senting complex data entities like records or objects. They
enhance code readability and organization by allowing related data to be
managed together.
 Definition:
struct Student {
char name [50];
int age;
};
Defines a structure Student with two members: a character array name
and
an integer age.
 Declaration and Initialization: struct Students = {"Alice", 20};
declares a variable s of type Student and initializes it.
 Access: Members are accessed using the dot operator (.), e.g., s.
name or s.age.
Structures can be nested (a structure within a structure) or used in arrays
(e.g., struct Student class [10]; for a class of 10 students).
Example:
#include<stdio.h>
struct Student{
char name [50];
int age;
};
int main() {
struct Students = {"Alice", 20};
printf("%s, %d\n", s.name, s.age);
return 0;
}

14 | P a g e
This program defines a Student structure, initializes an instance, and prints
its members, outputting "Alice, 20". Structures are particularly useful in
applications requiring grouped data, such as databases or configuration
settings.
9. File handling:
File handling in C enables reading from and writing to files, allowing data
persis-tence beyond program execution. Operations are performed using
FILE pointers and functions from stdio.h.
 Opening a File: FILE *fp = fopen("file.txt", "mode"); opens a file in a
specified mode (e.g., "r" for reading, "w" for writing, "a" for
appending). If the file cannot be opened (e.g., due to non-existence
in read mode), fopen returns NULL.
 Closing a File: fclose(fp); closes the file, flushing any buffered data
and freeing resources.
 Formatted I/O:
- fprintf(fp, "format", var1, var2, ...): Writes formatted data to the file,
similar to printf.
- fscanf (fp, "format", &var1, &var2, ...): Reads formatted data from
the file, similar to scanf.
 String I/O:
- fputs(str, fp): Writes a string to the file.
- fgets(str, size, fp): Reads up to size-1 characters or until a new-line
or end-of-file, storing the result in str.
 End of File (EOF): EOF is a macro indicating the end of a file, typically
-1. Functions like fscanf return EOF when no more data can be read.
Example:
#include <stdio.h>
int main() {
FILE *fp fopen("test.txt", "w");
if (fp== NULL)
{
printf("Error opening file\n");
return 1;
}

15 | P a g e
fprintf(fp, "Hello, File!");
fclose(fp);
fpfopen("test.txt", "r");
if (fp ==NULL) {
printf("Error opening file\n");
return 1;
}
char buffer [50];
fgets (buffer, 50, fp);
printf("Read from file: %s\n", buffer);
fclose(fp);
return 0;
}
This program writes "Hello, File!" to test.txt, then reads and prints it. The if
(fp==NULL) checks ensure robustness by handling file opening failures,
which could occur due to permission issues or file non-existence. File
handling is crucial for applications requiring data storage.

STANDARD C LIBRARY FUNCTIONS


This section outlines the standard C library functions utilized in the project,
detailing their syntax and functionality, with additions inspired by the
headers.h file usage. Only library functions are explained, with no
reference to user-defined functions. These functions are grouped by
header files, providing a structured reference for their usage in C
programming, including the library management system context.
1. stdio.h – Input and Output Operations:
The stdio.h library provides functions for standard input and output
operations, extensively used in the Quiz Game System for console
interactions and file handling.
1.1. printf()
Syntax:
printf("format", var1, var2, ...);
Functionality:

16 | P a g e
 Outputs formatted text to the console.
 Uses format specifiers (%s for strings, %d for integers, etc.).
 Returns the number of characters printed or a negative value on
error.
Example (Displaying quiz question):
printf("\n%s", q.question);
Usage in Project: Used to display quiz questions and options.
1.2. scanf()
syntax:
scanf ("format", &var1, &var2, ...);
Functionality:
 Reads formatted input from the user and stores values in variables.
 Requires & for passing addresses of variables (except for strings).
 Returns the number of successfully assigned items or EOF on failure.
Example (Getting user input for answer selection):
scanf("%d", &answer);
Usage in Project: Captures user answers in the quiz.

1.3. fopen()
Syntax:
FILE *fopen(const char *filename, const char *mode);
Functionality:
 Opens a file in the specified mode ("r", "w", "a", "rb", "wb", etc.).
 Returns a pointer to FILE or NULL on failure.
Example (Opening quiz file for reading):
FILE* fp = fopen("quiz.dat", "rb");
Usage in Project: Reads quiz questions stored in a binary file.
1.4. fwrite()
syntax:
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

17 | P a g e
Functionality:
 Writes data from memory (ptr) to a file.
 Returns the number of elements written successfully.
Example (Saving quiz questions to a file):
fwrite(&q, sizeof(QUESTIONS), 1, fp);
Usage in Project: Used in AddQuestions() to store quiz data persistently.

1.5. fread()
Syntax:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
Functionality:
 Reads data from a file into memory.
 Returns the number of elements successfully read.
Example (Reading quiz questions from a file):
fread(&q, sizeof(QUESTIONS), 1, fp);
Usage in Project: Retrieves stored quiz data for gameplay.

1.6. fclose()
Syntax:
int fclose(FILE *stream);
Functionality:
 Closes a file and flushes the output buffer.
 Returns 0 on success or EOF on error.
Example (Closing the file after writing questions):
fclose(fp);
Usage in Project: Ensures proper file handling to avoid memory leaks.

2. string.h – String Manipulation:


The string.h library provides functions for manipulating character arrays
(strings), used for handling user input and passwords.

18 | P a g e
2.1. strcmp()
Syntax:
int strcmp(const char *str1, const char *str2);
Functionality:
 Compares two strings lexicographically.
 Returns 0 if they are equal, a negative value if str1 is less than str2,
and a positive value if str1 is greater.
Example (Checking if user input matches password):
if (strcmp(input_pass, PASSWORD) != 0) {
printf("Wrong password\n");
}
Usage in Project: Used for password verification in CheckPassword().

2.2. strcpy()
Syntax:
char *strcpy(char *dest, const char *src);
Functionality:
 Copies the string src into dest, including the null terminator (\0).
 The destination buffer must be large enough to hold the copied
string.
Example (Copying a question into a structure):
strcpy(q.question, "What is 2+2?");
Usage in Project: Used when adding new questions.

2.3. strlen()
Syntax:

19 | P a g e
size_t strlen(const char *str);
Functionality:
 Returns the length of a string (excluding the null terminator).
Example (Validating password length):
if (strlen(input_pass) < 6) {
printf("Password too short!\n");
}
Usage in Project: Ensures valid input length.

3. stdlib.h – General Utilities


The stdlib.h library provides functions for memory management and
system commands.
3.1. system()
Syntax:
int system(const char *command);
Functionality:
 Executes a system command (e.g., clearing the console).
 Returns a status code.
Example (Clearing the screen):
system("cls"); // Windows
Usage in Project: Improves the user interface by clearing the screen.

3.2. malloc() and free()

20 | P a g e
Syntax:
void *malloc(size_t size);
void free(void *ptr);
Functionality:
 malloc() dynamically allocates memory.
 free() deallocates memory to prevent leaks.
Example (Allocating memory for a question):
QUESTIONS *q = (QUESTIONS*) malloc(sizeof(QUESTIONS));
Usage in Project: Could be used for dynamically handling quiz data.

4. windows.h – Windows-Specific Functions


The windows.h library provides functions for Windows system operations,
including sleep and threading.
4.1. sleep()
Syntax:
void Sleep(DWORD milliseconds);
Functionality:
Pauses execution for a given number of milliseconds.
Example (Creating a countdown timer):
Sleep(1000); // Waits for 1 second
Usage in Project: Used in the countdown timer for time-limited answers.
4.2. CreateThread()
Syntax:
HANDLE CreateThread(...);
Functionality:

21 | P a g e
Creates a new thread to run a function concurrently.
Example (Starting a countdown timer in a separate thread):
HANDLE timerThread = CreateThread(NULL, 0, countdownTimer, NULL, 0,
&threadID);
Usage in Project: Runs the countdown timer while waiting for user input.
5. time.h-Time Management:
The time.h library provides functions to manage and track time.
5.1. time()
Syntax:
time_t time(time_t *timer);
Functionality:
Gets the current system time.
Usage in Project: Could be used to track quiz duration or timestamps.

6. Operators and Utilities


This subsection includes key C operators and utilities often used with
library functions, particularly relevant to quiz.h (or any header file in the
project).
6.1. sizeof
Syntax: sizeof (type) or sizeof (expression)
Functionality:
 Returns the size (in bytes) of a type or variable at compile time.
 Commonly used for memory allocation (e.g.,
malloc(sizeof(QUESTIONS))) and file operations (e.g., fwrite()).
Example (Finding memory size of the QUESTIONS structure):
printf("Size of QUESTIONS structure: %lu bytes\n", sizeof(QUESTIONS));
Usage in Project:
Used in fwrite() and fread() to determine how much data should be
written/read.
fwrite(&q, sizeof(QUESTIONS), 1, fp);

22 | P a g e
6.2. #define(Macro definition)
Syntax:
#define MACRO_NAME value
Functionality:
 Defines a macro or constant for use throughout the program.
 Replaces instances of MACRO_NAME with value during
preprocessing.
Example (Defining constants for password and time limit):
#define PASSWORD "IMGROOT"
#define TIME_LIMIT 20
Usage in Project:
 Used to set predefined values like the admin password and quiz
timer.

6.3. #ifndef (Include Guards)


Syntax:
#ifndef MACRO_NAME
#define MACRO_NAME
... code ...
#endif
Functionality:
 Prevents multiple inclusions of a header file.
 Ensures that definitions and declarations are processed only once.
Example (Include guard in quiz.h):
#ifndef QUIZ_H
#define QUIZ_H

23 | P a g e
#define TIME_LIMIT 20
#endif
Usage in Project:
 Protects header files from being included multiple times, preventing
compilation errors.

7. Main Algorithm
The Quiz Game System begins its execution in the main.c file, where the
program continuously displays a menu for the user. The user can choose to
add quiz questions (if they have admin access), play the quiz, or exit the
program. If the user selects the admin function, they must enter a
password before they are allowed to add new quiz questions. If they
choose to play the quiz, the program reads questions from a binary file
(quiz.dat) and starts the game. This main loop continues running until the
user selects the exit option, ensuring a structured and interactive
experience.

8. User Authentication Functions


To maintain security and restrict unauthorized access to quiz
modifications, the system implements a password authentication
mechanism. When a user attempts to add new questions, they are
prompted to enter the predefined admin password. If the entered
password matches the stored value, they gain access to the question
management system. Otherwise, the system denies access and redirects
them back to the main menu. This mechanism ensures that only
authorized users can modify the quiz database, preventing accidental or
malicious changes.

9. Menu Functions
The Quiz Game System features a structured menu that allows users to
navigate through different functionalities. The main menu provides three
primary options: adding quiz questions (admin-only), playing the quiz, and
exiting the program. If the user is an admin, they can access a submenu
where they can input new quiz questions along with four answer choices
and specify the correct option. Meanwhile, players who choose to take the
quiz are directed to a separate section where questions are loaded from a
file and presented one by one. This menu-driven approach enhances

24 | P a g e
usability, ensuring that both administrators and players can efficiently
interact with the system.

10. Question Management Functions


The system allows administrators to manage quiz questions efficiently.
When an admin chooses to add a new question, they are prompted to
enter the question text followed by four possible answers. They must also
specify which option is correct. The entered data is then stored in a binary
file (quiz.dat) to ensure persistence across multiple sessions. Each
question entry is carefully formatted, and input validation ensures that the
correct option falls within the range of 1 to 4. This feature allows the quiz
database to be expanded dynamically without modifying the program’s
source code.

11. Quiz Gameplay Functions


The quiz experience for players is designed to be both engaging and
challenging. When a player starts the quiz, the system reads questions
from the binary file and presents them sequentially. Each question is
displayed along with four answer choices, and the player must select one
by entering the corresponding number. To introduce a competitive
element, a countdown timer of 20 seconds is enforced for each question. If
the player fails to answer within the time limit, the system automatically
moves on to the next question. The program then checks whether the
chosen answer is correct and provides immediate feedback. At the end of
the quiz, the player’s final score is displayed, indicating the number of
correct answers out of the total attempted.

12. Time-Limited Answer System (Countdown Timer)


A key feature of the Quiz Game System is the real-time countdown timer,
which ensures that each question must be answered within a fixed time
limit. This feature is implemented using multithreading, where a separate
thread continuously updates the remaining time while waiting for user
input. If the countdown reaches zero before the player enters a response,
the system automatically marks the question as unanswered and moves
on to the next one. This mechanism prevents players from taking too long
on a single question, maintaining the pace and excitement of the game.

13. File Handling Functions

25 | P a g e
The system relies on file handling to store and retrieve quiz questions
efficiently. When an administrator adds new questions, they are written to
a binary file (quiz.dat) using the fwrite() function. During gameplay, the
quiz questions are loaded from the same file using fread(), ensuring that
the stored data remains intact across multiple quiz sessions. Proper file
handling techniques are used to prevent errors, such as ensuring that the
file is successfully opened before attempting to read or write data. By
using a binary file format, the system optimizes storage space and
enhances data integrity.

14. Score Management Functions


At the end of the quiz, the system calculates the player’s final score based
on the number of correct answers. This score is displayed on the screen,
providing immediate feedback to the user. The scoring mechanism ensures
that players receive recognition for their performance, motivating them to
improve in subsequent attempts. If required, the system could be
extended to store scores in a file for future reference or leaderboard
functionality.

15. Utility Functions


To improve usability, the system includes several utility functions such as
clearing the screen, displaying formatted headers, and handling user input
validation. The clear screen function ensures that each new section of the
quiz is presented cleanly without cluttering the terminal. Additionally, the
countdown timer adds a real-time gaming experience, making the quiz
more dynamic and interactive. These utilities work together to enhance
the overall user experience, making the quiz system smooth and
professional.

Algorithm 1: Quiz Platform Main Algorithm


1. Start Program
2. Repeat until user chooses to exit:
1. Display Menu:
(1) Add Questions (Admin Only)
(2) Play Quiz
(3) Quit

26 | P a g e
2. Get User Input for Choice
3. If choice = 1,
Execute CheckPassword()
4. Else if choice = 2,
Execute PlayQuiz()
5. Else if choice = 3,
print exit message and break loop.
6. Else,
print an invalid input message and repeat.
7. End Program

Algorithm 2: Admin Authentication Algorithm


1. Start

2. Prompt for Admin Password


3. Get user input (input_pass)
4. If password is correct,
call AddQuestions()
5. .Else,

Algorithm 3: Add Questions Algorithm


1. Start
2. Open quiz file (quiz.dat) in append mode.
If file fails to open, print an error message and return.
3. Repeat until admin chooses to stop:
1. Get question text from the user.
2. Get 4 options from the user
3. Get correct answer (1-4)
If input is invalid, prompt again.
4. Write question to file
5. Ask admin if they want to add another question.
4. Close file and return to menu.

27 | P a g e
5. End

Algorithm 4: Start Quiz Algorithm


1. start
2. Open quiz file (quiz.dat) in read mode.
If file fails to open, print an error message and return
3. Initialize score = 0, total = 0
4. Repeat for each question in the file:
1. Display question and options.
2. Start countdown timer (20 sec) in a separate thread.
3. Get user answer (1-4).
If input is invalid, prompt again unless time runs out.

4. If time is up, print timeout message and move to next question.


5. Else, check if answer is correct:
If correct, increase score.
Else,
display correct answer.
5. Close file and display final score.
6. End

Algorithm 5: Countdown Timer Algorithm


1. Start
2. Initialize timer with 20 seconds.
3. Repeat while time > 0:
1. Print remaining time in seconds.
2. Wait 1 second.
3. If time runs out, set timeUp = 1 and print timeout message.
4. End countdown.
5.End

Algorithm 6: Input Validation Algorithm


1. Start

28 | P a g e
2. Prompt user for input (1-4)
3. Repeat until input is valid:
If input is not an integer or not in range, display an error and ask
again.
If time runs out, skip input validation.
4. Return valid input.
5.end

Algorithm 7: Question File Handling Algorithm


1.Start
2. Open quiz file (quiz.dat).
If it doesn’t exist, display error and return.
3. For each question:
Read data from file Store in QUESTIONS struct
Display on screen
4. Close file after reading all questions.
5.End

Algorithm 8: Quiz Score Calculation Algorithm


1. Start
2. Initialize score = 0, total = 0.
3. For each question answered:
If answer is correct, increment score.
If answer is wrong, display correct answer.
4. After all questions, display final score score/total.
5.end

29 | P a g e
Flowchart for Main Program

Start

Display Main
Menu:
1.Add Questions
2.Play Quiz
3.Quit

30 | P a g e
Read
Choice
from user

Choic Choic Choic


e==1 e==2 e==3
? ? ?

Call Call
CheckPasswor PlayQuiz( Stop
d() )

31 | P a g e
Flowchart for AddQuestions()

Start

Open file in
Appending
Mode

Input
Question

Input
Options (1-
4)

Input Correct
Option

Yes
Add
more?

No

Back to Main
Menu

32 | P a g e
Flowchart for PlayQuiz()

Start

Open Question
file in reading
mode

Read Question and


Start Timer Thread

Display
Questions and
Options

Wait for Answer Input


or Time Expiration

Time Answer
up? received?

Yes Yes

Skip Validate answer


Answer and Update
Score
Yes

Next
Questio
n?
No
Display Final Stop
Score

33 | P a g e
Flowchart for Timer Thread

Start

Start 20 second
countdown

Update time display


every second

Time Interrupted (Answer


reaches Received)
0?

Yes Stop

Set time up
Flag

Stop

34 | P a g e
Flowchart for CheckPassword()

Start

Read
password
from user

No
Password
== Display
‘IMGROO Error
T’

Yes

Go to
Call main
AddQuestions menu
()

SOURCE CODE

35 | P a g e
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>

#define PASSWORD "IMGROOT"


#define TIME_LIMIT 20
#define MAX_QUESTIONS 100 // Max limit for questions

typedef struct {
char question[100];
char option[4][100];
int correctopt;
} QUESTIONS;

volatile int timeUp = 0;


int totalQuestions = 0;
char questionsList[MAX_QUESTIONS][100];
char optionsList[MAX_QUESTIONS][4][100]; // New array to store options
int userAnswers[MAX_QUESTIONS];
int correctAnswers[MAX_QUESTIONS];

// Countdown Timer Thread Function


DWORD WINAPI countdownTimer(LPVOID param) {
for (int i = TIME_LIMIT; i >= 0; i--) {
if (timeUp) return 0;
printf("\rTime left: %d seconds ", i);
fflush(stdout);

36 | P a g e
Sleep(1000);
}
timeUp = 1;
printf("\nTime's up! Moving to next question...\n");
return 0;
}

// Function to get a valid integer input


int getValidInteger() {
int num;
while (scanf("%d", &num) != 1) {
printf("Invalid input! Enter a valid number: ");
while (getchar() != '\n'); // Clear input buffer
}
return num;
}

void AddQuestions();
void CheckPassword();
void PlayQuiz();
void ReviewIncorrectAnswers();

int main() {
int choice;
while (1) {
printf("\nWhat do you want to do?\n1. Add questions (Only admins)\
n2. Play Quiz\n3. Quit\nYour choice: ");
choice = getValidInteger();

if (choice == 1)

37 | P a g e
CheckPassword();
else if (choice == 2)
PlayQuiz();
else if (choice == 3) {
printf("\nExiting.....\n");
break;
}
else {
printf("Enter a proper number.\n");
}
}
return 0;
}

void AddQuestions() {
FILE* fp = fopen("quiz.dat", "ab");
if (!fp) {
printf("\nError opening file.....\n");
return;
}

QUESTIONS q;
char opt;
do {
getchar(); // Clear leftover newline
printf("Enter question: ");
fgets(q.question, sizeof(q.question), stdin);
q.question[strcspn(q.question, "\n")] = 0; // Remove newline

38 | P a g e
for (int i = 0; i < 4; i++) {
printf("Enter option %d: ", i + 1);
fgets(q.option[i], sizeof(q.option[i]), stdin);
q.option[i][strcspn(q.option[i], "\n")] = 0; // Remove newline
}

printf("Enter the correct option (1-4): ");


q.correctopt = getValidInteger();
while (q.correctopt < 1 || q.correctopt > 4) {
printf("\nEnter a valid option (1-4): ");
q.correctopt = getValidInteger();
}

fwrite(&q, sizeof(QUESTIONS), 1, fp);


printf("Question added successfully!\n");

printf("Add more questions (Y/N)? ");


getchar(); // Capture newline
opt = getchar();
getchar(); // Capture second newline

} while (opt == 'y' || opt == 'Y');

fclose(fp);
}

void CheckPassword() {
printf("Enter password: ");
char input_pass[20];

39 | P a g e
scanf("%s", input_pass);

if (strcmp(input_pass, PASSWORD) != 0) {
printf("Wrong password! Returning to main menu...\n");
return;
} else {
AddQuestions();
}
}

void PlayQuiz() {
FILE* fp = fopen("quiz.dat", "rb");
if (!fp) {
printf("Error opening file. Returning to main menu...\n");
return;
}

QUESTIONS q;
int score = 0, total = 0, answer;
HANDLE timerThread;
DWORD threadID;

while (fread(&q, sizeof(QUESTIONS), 1, fp)) {


if (total >= MAX_QUESTIONS) break; // Avoid overflow

timeUp = 0;
printf("\n%s", q.question);
strncpy(questionsList[total], q.question, 100); // Save question

40 | P a g e
// Save options for this question
for (int i = 0; i < 4; i++) {
strncpy(optionsList[total][i], q.option[i], 100);
printf("\n%d. %s", i + 1, q.option[i]);
}

printf("\nYou have %d seconds to answer...\n", TIME_LIMIT);


timerThread = CreateThread(NULL, 0, countdownTimer, NULL, 0,
&threadID);

printf("Your answer (1-4): ");


while (1) {
if (timeUp) break;
answer = getValidInteger();
if (answer >= 1 && answer <= 4) break;
printf("Invalid choice! Enter a number between 1-4: ");
}

if (!timeUp) {
TerminateThread(timerThread, 0);
CloseHandle(timerThread);

userAnswers[total] = answer; // Save user choice (1-4)


correctAnswers[total] = q.correctopt; // Save correct answer (1-4)

if (answer == q.correctopt) {
printf("Correct!\n");
score++;
} else {

41 | P a g e
printf("Wrong! Correct answer was %s\n", q.option[q.correctopt -
1]);
}
} else {
userAnswers[total] = 0; // Mark unanswered questions as 0
correctAnswers[total] = q.correctopt;
}

total++;
}

fclose(fp);
totalQuestions = total; // Store total questions for review

// Display final score


printf("\nFinal Score: %d/%d\n", score, total);

// Call function to review incorrect answers


ReviewIncorrectAnswers();
}

// Function to review incorrect answers with option text


void ReviewIncorrectAnswers() {
printf("\nReview of incorrect answers:\n");
int found = 0;
for (int i = 0; i < totalQuestions; i++) {
if (userAnswers[i] != correctAnswers[i]) {
found = 1;
printf("\nQ: %s", questionsList[i]);
// Show user's answer (if answered) or "No answer"

42 | P a g e
printf("\nYour answer: %s",
userAnswers[i] ? optionsList[i][userAnswers[i] - 1] : "No
answer");
// Show correct answer
printf("\nCorrect answer: %s\n", optionsList[i][correctAnswers[i] -
1]);
}
}
if (!found) {
printf("Great job! You got all answers correct!\n");
}
}

OUTPUT
Home page:

Add questions:

43 | P a g e
Wrong password:

Play quiz:

44 | P a g e
CONCLUSION

45 | P a g e
In conclusion, the implementation of the EduQuiz System marks a pivotal
step forward in revolutionizing educational assessment and engagement
within academic environments. Designed as a comprehensive and user-
centric platform, the EduQuiz System empowers students and educators
alike by simplifying the process of quiz participation and management,
while enhancing the overall learning experience through structured and
interactive means.

With its robust suite of features—secure administrator access for question


curation, timed quiz sessions, real-time performance feedback, and
detailed review of responses with option-text clarity—the EduQuiz System
delivers a seamless and transparent experience. Administrators benefit
from efficient tools to maintain a dynamic question database, ensuring
content relevance and variety, while participants enjoy an intuitive
interface that fosters active learning and immediate self-assessment. The
ability of the EduQuiz System to store questions persistently and provide
insightful post-quiz reviews elevates its utility as an educational tool.

By automating time-sensitive interactions and offering instant feedback on


user performance, the EduQuiz System not only increases engagement but
also cultivates an environment conducive to effective knowledge
evaluation. Leveraging technology to streamline quiz administration and
enrich participant interaction, the EduQuiz System establishes a new
benchmark for educational quiz platforms, ultimately enhancing the
academic journey for all stakeholders involved.

46 | P a g e

You might also like